huatong 发表于 2012-10-8 15:33:19

第一次使用流水线设计,16位二进制转换成5位十进制,这个应...

流水线听得多了,但一直没有使用过,今天要用到将16进制转换到10进制,想到好可以使用流水线提高速度,所以就试了一下,请大家指教.我想这个应该算是流水线了吧,以下是代码及testbenchmodule H2D(clk,rst,hex,dec);
        input clk;
        input rst;
        input hex;
        output dec;

        reg TenThousand;        //万位
        reg d1;
       
        reg Thousand;                //千位
        reg d2;
       
        reg Hundred;                //百位
        reg d3;
       
        reg Ten;                        //十位
        reg d4;
       
        reg dout;
       
        initial begin
                TenThousand=4'h0;
                d1=16'h0000;
                Thousand=8'h00;
                d2=16'h0000;
                Hundred=12'h000;
                d3=16'h0000;
                d4=16'h0000;
                dout=20'h0_0000;
        end
       
        //万位
        always@(posedge clk) begin
                if(!rst) begin                                        //同步复位
                        TenThousand<=4'h0;
                        d1<=16'h0000;
                end else begin
                        if(hex>59999) begin
                                TenThousand<=4'd6;
                                d1<=hex-16'd60000;
                        end else if(hex>49999) begin
                                TenThousand<=4'd5;
                                d1<=hex-16'd50000;
                        end else if(hex>39999) begin
                                TenThousand<=4'd4;
                                d1<=hex-16'd40000;
                        end else if(hex>29999) begin
                                TenThousand<=4'd3;
                                d1<=hex-16'd30000;
                        end else if(hex>19999) begin
                                TenThousand<=4'd2;
                                d1<=hex-16'd20000;
                        end else if(hex>9999) begin
                                TenThousand<=4'd1;
                                d1<=hex-16'd10000;
                        end else begin
                                TenThousand<=4'd0;
                                d1<=hex;
                        end
                end
        end
        //千位
        always@(posedge clk) begin
                if(!rst) begin
                        Thousand<=8'h00;
                        d2<=16'h0000;
                end else begin
                        if(d1>8999) begin
                                Thousand<={TenThousand,4'd9};
                                d2<=d1-16'd9000;
                        end else if(d1>7999) begin
                                Thousand<={TenThousand,4'd8};
                                d2<=d1-16'd8000;
                        end else if(d1>6999) begin
                                Thousand<={TenThousand,4'd7};
                                d2<=d1-16'd7000;
                        end else if(d1>5999) begin
                                Thousand<={TenThousand,4'd6};
                                d2<=d1-16'd6000;
                        end else if(d1>4999) begin
                                Thousand<={TenThousand,4'd5};
                                d2<=d1-16'd5000;
                        end else if(d1>3999) begin
                                Thousand<={TenThousand,4'd4};
                                d2<=d1-16'd4000;
                        end else if(d1>2999) begin
                                Thousand<={TenThousand,4'd3};
                                d2<=d1-16'd3000;
                        end else if(d1>1999) begin
                                Thousand<={TenThousand,4'd2};
                                d2<=d1-16'd2000;
                        end else if(d1>999) begin
                                Thousand<={TenThousand,4'd1};
                                d2<=d1-16'd1000;
                        end else begin
                                Thousand<={TenThousand,4'd0};
                                d2<=d1;
                        end
                end
        end
        //百位
        always@(posedge clk) begin
                if(!rst) begin
                        Hundred<=12'h000;
                        d3<=16'h000;
                end else begin
                        if(d2>899) begin
                                Hundred<={Thousand,4'd9};
                                d3<=d2-16'd900;
                        end else if(d2>799) begin
                                Hundred<={Thousand,4'd8};
                                d3<=d2-16'd800;
                        end else if(d2>699) begin
                                Hundred<={Thousand,4'd7};
                                d3<=d2-16'd700;
                        end else if(d2>599) begin
                                Hundred<={Thousand,4'd6};
                                d3<=d2-16'd600;
                        end else if(d2>499) begin
                                Hundred<={Thousand,4'd5};
                                d3<=d2-16'd500;
                        end else if(d2>399) begin
                                Hundred<={Thousand,4'd4};
                                d3<=d2-16'd400;
                        end else if(d2>299) begin
                                Hundred<={Thousand,4'd3};
                                d3<=d2-16'd300;
                        end else if(d2>199) begin
                                Hundred<={Thousand,4'd2};
                                d3<=d2-16'd200;
                        end else if(d2>99) begin
                                Hundred<={Thousand,4'd1};
                                d3<=d2-16'd100;
                        end else begin
                                Hundred<={Thousand,4'd0};
                                d3<=d2;
                        end
                end
        end
        //十位
        always@(posedge clk) begin
                if(!rst) begin
                        Ten<=16'h0000;
                        d4<=16'h0000;
                end else begin
                        if(d3>89) begin
                                Ten<={Hundred,4'd9};
                                d4<=d3-16'd90;
                        end else if(d3>79) begin
                                Ten<={Hundred,4'd8};
                                d4<=d3-16'd80;
                        end else if(d3>69) begin
                                Ten<={Hundred,4'd7};
                                d4<=d3-16'd70;
                        end else if(d3>59) begin
                                Ten<={Hundred,4'd6};
                                d4<=d3-16'd60;
                        end else if(d3>49) begin
                                Ten<={Hundred,4'd5};
                                d4<=d3-16'd50;
                        end else if(d3>39) begin
                                Ten<={Hundred,4'd4};
                                d4<=d3-16'd40;
                        end else if(d3>29) begin
                                Ten<={Hundred,4'd3};
                                d4<=d3-16'd30;
                        end else if(d3>19) begin
                                Ten<={Hundred,4'd2};
                                d4<=d3-16'd20;
                        end else if(d3>9)        begin
                                Ten<={Hundred,4'd1};
                                d4<=d3-16'd10;
                        end else begin
                                Ten<={Hundred,4'd0};
                                d4<=d3;
                        end
                end
        end
        //个位
        always@(posedge clk) begin
                if(!rst) begin
                        dout<=20'h0_0000;
                end else begin
                        dout<={Ten,d4};
                end
        end
        assign dec=dout;
       
endmodule

testbench`timescale 1ps/1ps
module tb;

        reg clk;
        reg rst;
        reg hex;
        wire dec;
       
        initial begin
                clk=0;
                rst=0;
                hex=16'h0000;
                #200000
                rst=1;
        end
       
        always #50000 clk=~clk;
        always #200000 hex=hex-1;
       
        H2D U0(.clk(clk),.rst(rst),.hex(hex),.dec(dec));

endmodule
RTL仿真

Flyback 发表于 2012-10-8 19:34:54

以我那好几十天的Verilog经验,表示全忘了,基本看不懂

NJ8888 发表于 2012-10-8 21:12:06

本帖最后由 NJ8888 于 2012-10-8 21:18 编辑

不像流水线概念(不过verilog我不用),另外BIN2BCD我贴过代码,看似比你简单。是VHDL的,原理上不是很直观,要靠时钟工作,不是组合逻辑
http://www.amobbs.com/thread-4215535-1-1.html

huatong 发表于 2012-10-8 21:44:15

NJ8888 发表于 2012-10-8 21:12 static/image/common/back.gif
不像流水线概念(不过verilog我不用),另外BIN2BCD我贴过代码,看似比你简单。是VHDL的,原理上不是很直观 ...

你这个是用状态机吧(不懂VHDL,但看起来很像是使用状态机的样子),这可不是流水线吧,
我想像中的流水线应该是这样的吧:
时刻0输入0xFFFF,时刻1输入0xFFFE ... ...
时刻5输出65535,时刻6输出65534 ... ...
数据源源不断的输入,经过流水线的延时后,数据也是源源不断的输出.
你那个程序用状态机,好是16个状态吧,应该不像是流水线啊.我的理解是:时钟0读入一个BIN,时钟15输出1个BCD,再在时钟16读入一个BIN,时钟31输出一个BCD.
如果这样要做成流水线,起码要16条流水线,而且每条流水线的状态机相差1位才可以.
以上是我的理解,不是是否正确,我还是一个FPGA的初学者,请指教.

NJ8888 发表于 2012-10-8 21:50:09

huatong 发表于 2012-10-8 21:44 static/image/common/back.gif
你这个是用状态机吧(不懂VHDL,但看起来很像是使用状态机的样子),这可不是流水线吧,
我想像中的流水线应该 ...

你你的理解对的,靠16个时钟把他《65536的数据转成20位BCD。与流水线没关系。

huatong 发表于 2012-10-8 21:54:41

NJ8888 发表于 2012-10-8 21:50 static/image/common/back.gif
你你的理解对的,靠16个时钟把他《65536的数据转成20位BCD。与流水线没关系。 ...

不过还是要谢谢你给我了一个思路,用你的方法可以做成一条16位深度的流水线,而且时钟会跑得更快.

richards 发表于 2012-10-8 21:55:23

/********************************************************************************
// @file    project/BinaryToBCD.v
// @authorRichards
// @version V1.0
// @date    28-May-2012
// @brief   8位二进制 转 BCD码
********************************************************************************/
module BinaryToBCD(bin,BCD,ONES,TENS,HUNDREDS);
input bin;
output BCD;
output ONES,TENS;
output HUNDREDS;
wire c1,c2,c3,c4,c5,c6,c7;
wire d1,d2,d3,d4,d5,d6,d7;

assign d1 = {1'b0,bin};
assign d2 = {c1,bin};
assign d3 = {c2,bin};
assign d4 = {c3,bin};
assign d5 = {c4,bin};
assign d6 = {1'b0,c1,c2,c3};
assign d7 = {c6,c4};

add3 m1(d1,c1);
add3 m2(d2,c2);
add3 m3(d3,c3);
add3 m4(d4,c4);
add3 m5(d5,c5);
add3 m6(d6,c6);
add3 m7(d1,c7);

assign ONES = {c5,bin};
assign TENS = {c7,c5};
assign HUNDREDS = {c6,c7};
assign BCD = {HUNDREDS,TENS,ONES};

endmodule

module add3(in,out);
input in;
output out;
reg out;

always @(in)
        case (in)
                4'b0000 : out <= 4'b0000;
                4'b0001 : out <= 4'b0001;
                4'b0010 : out <= 4'b0010;
                4'b0011 : out <= 4'b0011;
                4'b0100 : out <= 4'b0100;

                4'b0101 : out <= 4'b1000;
                4'b0110 : out <= 4'b1001;
                4'b0111 : out <= 4'b1010;
                4'b1000 : out <= 4'b1011;
                4'b1001 : out <= 4'b1100;
                default : out <= 4'b0000;
        endcase
endmodule

huatong 发表于 2012-10-8 22:02:04

richards 发表于 2012-10-8 21:55 static/image/common/back.gif
/********************************************************************************
// @file    proje ...

谢谢你哦.

richards 发表于 2012-10-8 22:04:11

huatong 发表于 2012-10-8 22:02 static/image/common/back.gif
谢谢你哦.

互相参考吧,你的设计思路也不错呢。那是我上学期做秒表时候用的BCD转换代码。

ctqvsly 发表于 2013-5-3 19:26:26

学习了!!!{:lol:}

冷血魔 发表于 2013-5-7 19:22:19

学习了~~~~

yixinyiyi 发表于 2013-6-30 18:50:14

BCD转十进制有方法的,坛子里有,你这样写太耗资源了

huatong 发表于 2013-6-30 19:05:56

本帖最后由 huatong 于 2013-6-30 19:07 编辑

yixinyiyi 发表于 2013-6-30 18:50 static/image/common/back.gif
BCD转十进制有方法的,坛子里有,你这样写太耗资源了

现在已经改了,40位二进制转换成8位十进制5级流水线.没有贴出来罢了/***********************************************************
        40位二进制转换为8位十进制
***********************************************************/
module BinaryToBCD(clk,bin,bcd);
inputclk;
input bin;
output bcd;
reg    bcd;

reg bin0,bin1,bin2,bin3,bin4;        // /*synthesis noprune*/;

always@(posedge clk) begin
        bin0<=bin;
        bin1<=bin0;
        bin2<=bin1;
        bin3<=bin2;
        bin4<=bin3;
end

wire o1,o2,o3;
wire i1;
Add3 c1({1'b0,bin0},o1);
Add3 c2({o1,bin0},o2);
Add3 c3({o2,bin0},o3);
assign i1={o1,o2,o3};

wire o21,o22,o23;
reg i2;
add3_8 c4({1'b0,i1,bin0},o21);
add3_8 c5({o21,bin0},o22);
add3_8 c6({o22,bin0},o23);
always@(posedge clk) i2<={o21,o22,o23};                                // 第一级流水线

wire o31,o32,o33;
wire i3;
add3_12 c7({1'b0,i2,bin1},o31);
add3_12 c8({o31,bin1},o32);
add3_12 c9({o32,bin1},o33);
assign i3={o31,o32,o33};

wire o41,o42,o43;
reg i4;
add3_16 c10({1'b0,i3,bin1},o41);
add3_16 c11({o41,bin1},o42);
add3_16 c12({o42,bin1},o43);
always@(posedge clk) i4<={o41,o42,o43};                                // 第二级流水线

wire o51,o52,o53;
wire i5;
add3_20 c13({1'b0,i4,bin2},o51);
add3_20 c14({o51,bin2},o52);
add3_20 c15({o52,bin2},o53);
assign i5={o51,o52,o53};

wire o61,o62,o63;
reg i6;
add3_24 c16({1'b0,i5,bin2},o61);
add3_24 c17({o61,bin2},o62);
add3_24 c18({o62,bin2},o63);
always@(posedge clk) i6<={o61,o62,o63};                                // 第三级流水线

wire o71,o72,o73;
wire i7;
add3_28 c19({1'b0,i6,bin3},o71);
add3_28 c20({o71,bin3},o72);
add3_28 c21({o72,bin3},o73);
assign i7={o71,o72,o73};

wire o81,o82,o83;
reg i8;
add3_32 c22({1'b0,i7,bin3},o81);
add3_32 c23({o81,bin3},o82);
add3_32 c24({o82,bin3},o83);
always@(posedge clk) i8<={o81,o82,o83};                                // 第四级流水线

wire o91,o92,o93;
wire i9;
add3_36 c25({1'b0,i8,bin4},o91);
add3_36 c26({o91,bin4},o92);
add3_36 c27({o92,bin4},o93);
assign i9={o91,o92,o93};

wire o101,o102,o103;
wire i10;
add3_40 c28({1'b0,i9,bin4},o101);
add3_40 c29({o101,bin4},o102);
assign i10={o101,o102,bin4};

always@(posedge clk) bcd<=i10;                                                        // 第五级流水线

endmodule


/*********** 4位比较加3模块 *************/
module Add3(in,out);
input in;
output reg out;

always@(in)
        case(in)
                4'b0000:                out<=4'b0000;
                4'b0001:                out<=4'b0001;
                4'b0010:                out<=4'b0010;
                4'b0011:                out<=4'b0011;
                4'b0100:                out<=4'b0100;
                //
                4'b0101:                out<=4'b1000;
                4'b0110:                out<=4'b1001;
                4'b0111:                out<=4'b1010;
                4'b1000:                out<=4'b1011;
                4'b1001:                out<=4'b1100;
                //
                default:                out<=4'b0000;
        endcase
endmodule

module add3_8(in,out);
        input in;
        output out;
       
        Add3 m1(in,out);
        Add3 m2(in,out);
endmodule

module add3_12(in,out);
        input in;
        output out;
       
        Add3 m1(in,out);
        add3_8 m2(in,out);
endmodule

module add3_16(in,out);
        input in;
        output out;
       
        Add3 m1(in,out);
        add3_12 m2(in,out);
endmodule

module add3_20(in,out);
        input in;
        output out;
       
        Add3 m1(in,out);
        add3_16 m2(in,out);
endmodule

module add3_24(in,out);
        input in;
        output out;
       
        Add3 m1(in,out);
        add3_20 m2(in,out);
endmodule

module add3_28(in,out);
        input in;
        output out;
       
        Add3 m1(in,out);
        add3_24 m2(in,out);
endmodule

module add3_32(in,out);
        input in;
        output out;
       
        Add3 m1(in,out);
        add3_28 m2(in,out);
endmodule

module add3_36(in,out);
        input in;
        output out;
       
        Add3 m1(in,out);
        add3_32 m2(in,out);
endmodule

module add3_40(in,out);
        input in;
        output out;
       
        Add3 m1(in,out);
        add3_36 m2(in,out);
endmodule
页: [1]
查看完整版本: 第一次使用流水线设计,16位二进制转换成5位十进制,这个应...