第一次使用流水线设计,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仿真
以我那好几十天的Verilog经验,表示全忘了,基本看不懂
。
本帖最后由 NJ8888 于 2012-10-8 21:18 编辑不像流水线概念(不过verilog我不用),另外BIN2BCD我贴过代码,看似比你简单。是VHDL的,原理上不是很直观,要靠时钟工作,不是组合逻辑
http://www.amobbs.com/thread-4215535-1-1.html 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的初学者,请指教. huatong 发表于 2012-10-8 21:44 static/image/common/back.gif
你这个是用状态机吧(不懂VHDL,但看起来很像是使用状态机的样子),这可不是流水线吧,
我想像中的流水线应该 ...
你你的理解对的,靠16个时钟把他《65536的数据转成20位BCD。与流水线没关系。 NJ8888 发表于 2012-10-8 21:50 static/image/common/back.gif
你你的理解对的,靠16个时钟把他《65536的数据转成20位BCD。与流水线没关系。 ...
不过还是要谢谢你给我了一个思路,用你的方法可以做成一条16位深度的流水线,而且时钟会跑得更快. /********************************************************************************
// @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
richards 发表于 2012-10-8 21:55 static/image/common/back.gif
/********************************************************************************
// @file proje ...
谢谢你哦. huatong 发表于 2012-10-8 22:02 static/image/common/back.gif
谢谢你哦.
互相参考吧,你的设计思路也不错呢。那是我上学期做秒表时候用的BCD转换代码。 学习了!!!{:lol:} 学习了~~~~ BCD转十进制有方法的,坛子里有,你这样写太耗资源了 本帖最后由 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]