数字模块实例-Verilog.doc

上传人:聆听****声音 文档编号:750498 上传时间:2023-04-30 格式:DOC 页数:61 大小:4.78MB
下载 相关 举报
数字模块实例-Verilog.doc_第1页
第1页 / 共61页
数字模块实例-Verilog.doc_第2页
第2页 / 共61页
数字模块实例-Verilog.doc_第3页
第3页 / 共61页
数字模块实例-Verilog.doc_第4页
第4页 / 共61页
数字模块实例-Verilog.doc_第5页
第5页 / 共61页
数字模块实例-Verilog.doc_第6页
第6页 / 共61页
数字模块实例-Verilog.doc_第7页
第7页 / 共61页
数字模块实例-Verilog.doc_第8页
第8页 / 共61页
数字模块实例-Verilog.doc_第9页
第9页 / 共61页
数字模块实例-Verilog.doc_第10页
第10页 / 共61页
数字模块实例-Verilog.doc_第11页
第11页 / 共61页
数字模块实例-Verilog.doc_第12页
第12页 / 共61页
数字模块实例-Verilog.doc_第13页
第13页 / 共61页
数字模块实例-Verilog.doc_第14页
第14页 / 共61页
数字模块实例-Verilog.doc_第15页
第15页 / 共61页
数字模块实例-Verilog.doc_第16页
第16页 / 共61页
数字模块实例-Verilog.doc_第17页
第17页 / 共61页
数字模块实例-Verilog.doc_第18页
第18页 / 共61页
数字模块实例-Verilog.doc_第19页
第19页 / 共61页
数字模块实例-Verilog.doc_第20页
第20页 / 共61页
亲,该文档总共61页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

数字模块实例-Verilog.doc

《数字模块实例-Verilog.doc》由会员分享,可在线阅读,更多相关《数字模块实例-Verilog.doc(61页珍藏版)》请在冰点文库上搜索。

数字模块实例-Verilog.doc

一、加、减法器 2

1、半加器 2

2、全加器 2

3、串行进位加法器(行波进位加法器) 4

4、超前进位加法器(先行进位加法器) 4

5、进位链加法器、跳跃进位加法器 7

6、进位旁路加法器、线性进位选择加法器等 9

7、减法器 9

二、乘法器 10

1、定点原码乘法器 10

2、加法树乘法器 12

3、查找表乘法器 13

4、布尔乘法器 14

三、CORDIC数字计算机 18

四、Johnson计数器 21

五、移位寄存器 22

1、串并转换模块 22

2生成伪随机数及伪随机序列应用设计 24

3桶形移位寄存器(循环移位寄存器) 27

六、编码译码器 29

1、差错控制编码 29

2、HDB3编码与译码 37

3曼彻斯特编译码器 39

RS(204,188)译码器 46

4、Gray码与二进制码的转换 46

5、NRZI编码 46

七、加密解密模块 48

1、DES加密模块 48

一、加、减法器

1、半加器

半加器:

输入为两个二进制数,输出产生两个二进制数,一个和位、一个进位,不包括来自低位的进位。

逻辑表达式为:

,其电路符号为:

2、全加器

在将两个多位二进制数相加时,除了最低位以外,每一位都应该考虑来自低位的进位,这种运算为全加,其电路为全加器。

逻辑表达式为:

电路图:

由半加器组成的结构如下:

Verilog模型

3、串行进位加法器(行波进位加法器)

依次将低位全加器的进位输出端CO接到高位全加器的进位输入端CI,就可以构成多位加法器。

//二进制行波进位加法器

moduleripple_carry_adder(x,y,cin,sum,cout);

parameter N=8;

input cin;

input[N-1:

0] x,y;

output[N-1:

0] sum;

output cout;

reg cout;

reg[N-1:

0] sum;

regq[N:

0];

always@(xoryorcin)begin:

ADDER

integeri;

q[0]=cin;

for(i=0;i<=N-1;i=i+1)begin

q[i+1]=(x[i]&y[i])|(x[i]&q[i])|(y[i]&q[i]);

sum[i]=x[i]^y[i]^q[i];

end

cout=q[N];

end

endmodule

4、超前进位加法器(先行进位加法器)

产生进位输出的情况是AB=1、A+B=1且CI=1,则得:

高位的进位输入不用等到低位计算完后就可得到,提高了计算速度,其电路结构如下:

其电路符号

Verilog描述:

GP生成器:

使用两个一位加法器与一个GP生成器设计两位的超前进位加法器

同样可以进行继续扩展

5、进位链加法器、跳跃进位加法器

modulecarry_chain_adder(x,y,cin,sum,cout);

parameter DSIZE=8;

input cin;

input[DSIZE-1:

0] x,y;

output[DSIZE-1:

0] sum;

output cout;

reg cout,q[DSIZE:

0],p[DSIZE-1:

0],g[DSIZE-1:

0];

reg[DSIZE-1:

0] sum;

always@(xoryorcin)begin:

ADDER

integeri;

q[0]=cin;

for(i=0;i

p[i]=x[i]^y[i];

g[i]=y[i];

q[i+1]=(p[i])?

q[i]:

g[i];

sum[i]=p[i]^q[i];

end

cout=q[DSIZE];

end

endmodule

//二进制跳跃进位加法器

modulecarry_skip_adder(x_in,y_in,c_in,sum,c_out);

parameter DSIZE=12;

parameter S=4;

input c_in;

input[DSIZE-1:

0] x_in,y_in;

output[DSIZE-1:

0] sum;

reg[DSIZE-1:

0]sum;

output c_out;

reg c_out;

integeri,j;

reg[DSIZE:

0]q;

always@(x_inory_inorc_in)begin

q[0]=c_in;

begin

carry_skip_add_cell(x_in[S-1:

0],y_in[S-1:

0],

q[0],q[S:

1]);

for(j=0;j<=S-1;j=j+1)

sum[j]=x_in[j]^y_in[j]^q[j];

carry_skip_add_cell(x_in[2*S-1:

S],y_in[2*S-1:

S],

q[S],q[2*S:

S+1]);

for(j=0;j<=S-1;j=j+1)

sum[S+j]=x_in[S+j]^y_in[S+j]^q[S+j];

carry_skip_add_cell(x_in[3*S-1:

2*S],y_in[3*S-1:

2*S],

q[2*S],q[3*S:

2*S+1]);

for(j=0;j<=S-1;j=j+1)

sum[2*S+j]=x_in[2*S+j]^y_in[2*S+j]^q[2*S+j];

end

c_out=q[DSIZE];

end

//S比特分组进位链

taskcarry_skip_add_cell;

input[S-1:

0]x,y;

inputcin;

output[S:

1]cout;

reg q[S:

0],p[S-1:

0],g[S-1:

0],accumulator,generalized_p;

integeri;

begin

q[0]=cin;

for(i=0;i<=S-1;i=i+1)begin

p[i]=x[i]^y[i];

g[i]=y[i];

q[i+1]=(p[i])?

q[i]:

g[i];

end

accumulator=p[0];

for(i=1;i<=S-1;i=i+1)

accumulator=accumulator&p[i];

generalized_p=accumulator;

cout[S]=(generalized_p)?

c_in:

q[S];

for(i=1;i<=S-1;i=i+1)

cout[i]=q[i];

end

endtask

endmodule

6、进位旁路加法器、线性进位选择加法器等

7、减法器

Verilog模型如下:

二、乘法器

1、定点原码乘法器

乘数与被乘数分别载入两个寄存器R1与R2中。

此外,还有一个寄存器A,A的初始值为0。

运算时,控制逻辑每次读乘数的一位。

若R1的最低位为1,则被乘数与A寄存器相加,并将结果存于A寄存器。

然后,A、R1这两个寄存器整体右移一位,A的最高位变成0,且A0进入R1的最高位,而R1的最低位丢弃。

若R1的最低位是0,则只需进行移位,不进行加法。

产生的2n位乘积存于A与R1寄存器中。

32位定点原码一位乘法流程图如下:

Verilog参考代码:

modulemult(start,resten,x,y,z,);

input resten;

input start;

regbusy;

input [2:

0] x;

input [2:

0] y;

output[5:

0]z;

reg[5:

0] z;

reg [2:

0]reg_x;

reg [2:

0] reg_y;

reg [3:

0] A;

reg [2:

0] temp_x;

integer i;

always@(xoryorrestenorstart)

begin

if(!

resten) begin

A =4'b0;

reg_x=3'b0;

reg_y=3'b0;

temp_x=3'b0;

z =6'b0;

busy =0;

end

elseif(start)begin

reg_x=x;

reg_y=y;

busy =1;

A =4'b0;

end

elsebegin

if(busy)

for(i=0;i<3;i=i+1)begin

if(y[i])temp_x=x;

else temp_x=3'b000;

A = A+{1'b0,temp_x};

reg_y = {A[0],reg_y[2:

1]};

A = A>>1;

end

z={A,reg_y};busy=0;

end

end

endmodule

2、加法树乘法器

moduleadd_tree_mult(out,a,b,clk);

output[15:

0]out;

input[7:

0]a,b;

inputclk;

wire[15:

0]out;

wire[14:

0]out1,c1;

wire[12:

0]out2;

wire[10:

0]out3,c2;

wire[8:

0]out4;

reg[14:

0]temp0;

reg[13:

0]temp1;

reg[12:

0]temp2;

reg[11:

0]temp3;

reg[10:

0]temp4;

reg[9:

0]temp5;

reg[8:

0]temp6;

reg[7:

0]temp7;

function[7:

0]mux8_1;

input[7:

0]operand;

inputsel;

begin

mux8_1=(sel)?

(operand):

8'b00000000;

end

endfunction

always@(posedgeclk)

begin

temp7<=mux8_1(a,b[0]);

temp6<=((mux8_1(a,b[1]))<<1);

temp5<=((mux8_1(a,b[2]))<<2);

temp4<=((mux8_1(a,b[3]))<<3);

temp3<=((mux8_1(a,b[4]))<<4);

temp2<=((mux8_1(a,b[5]))<<5);

temp1<=((mux8_1(a,b[6]))<<6);

temp0<=((mux8_1(a,b[7]))<<7);

end

assign out1=temp0+temp1;

assign out2=temp2+temp3;

assign out3=temp4+temp5;

assign out4=temp6+temp7;

assign c1=out1+out2;

assign c2=out3+out4;

assign out=c1+c2;

endmodule

3、查找表乘法器

查找表乘法器是将乘积直接存放在存储器中,将操作数作为地址访问存储器,得到的输出数据就是乘法器的结果。

查找表乘法器的速度只局限于所使用存储器的存取速度。

modulelookup_mult(out,a,b,clk);

output[7:

0]out;

input[3:

0]a,b;

inputclk;

reg[7:

0]out;

reg[1:

0]firsta,firstb;

reg[1:

0]seconda,secondb;

wire[3:

0]outa,outb,outc,outd;

always@(posedgeclk)

begin

firsta=a[3:

2];seconda=a[1:

0];

firstb=b[3:

2];secondb=b[1:

0];

end

lookup m1(outa,firsta,firstb,clk),

m2(outb,firsta,secondb,clk),

m3(outc,seconda,firstb,clk),

m4(outd,seconda,secondb,clk);

always@(posedgeclk)

begin

out=(outa<<4)+(outb<<2)+(outc<<2)+outd;

end

endmodule

modulelookup(out,a,b,clk);

output[3:

0]out;

input[1:

0]a,b;

inputclk;

reg[3:

0]out;

reg[3:

0]address;

always@(posedgeclk)

begin

address={a,b};

case(address)

4'h0:

out=4'b0000;

4'h1:

out=4'b0000;

4'h2:

out=4'b0000;

4'h3:

out=4'b0000;

4'h4:

out=4'b0000;

4'h5:

out=4'b0001;

4'h6:

out=4'b0010;

4'h7:

out=4'b0011;

4'h8:

out=4'b0000;

4'h9:

out=4'b0010;

4'ha:

out=4'b0100;

4'hb:

out=4'b0110;

4'hc:

out=4'b0000;

4'hd:

out=4'b0011;

4'he:

out=4'b0110;

4'hf:

out=4'b1001;

default:

out='bx;

endcase

end

endmodule

4、布尔乘法器

Booth算法通过以移位代替某些运算来提高乘法的运算速度。

Booth算法是补码乘法的算法,基本公式为:

[X*Y]补=[X]补*[Yn-1Yn-2…..Y0]-[X]补*Yn。

公式说明如果乘数为正,则将乘数的尾数与被乘数相乘即可,如果乘数为负,那么在乘法运算之后,还要再减去被乘数才能得到最后的乘积。

公式变形为[X*Y]补=[X]补*[2^n(Yn-1-Yn)+2^n-1(Yn-2-Yn-1)+……+2^0(0-Y0)]。

从变形公式中可以看出,如果在乘数Y的末位Y0之后再增设一个附加位Y-1,其初始值为0,对乘数Y的值并无影响,则{(Yi-1,Yi)[X]补}就是每一次的部分积,该部分的位权就是2^i。

这种方法即为补码一位乘,即每次只处理一位乘数。

运算流程:

乘数与被乘数分别载入Q和M寄存器内,同时,还有一个1位寄存器,位于Q寄存器最低位Q0的右边,成为Q’。

乘法的结果出现在A和Q寄存器中。

A与Q’初始值为0。

控制逻辑也是每次扫描乘数的一位,但同时它也要检查右边的一位。

若两位相同,则A、Q和Q’寄存器的所有位向右移一位。

若两位不同,则根据两位是1-0还是0-1,决定被乘数加到A寄存器,还是有A寄存器减去被乘数,加减之后再右移一位。

也就是说,右移总是要进行的。

右移是{A,Q,Q’}的右移且是算术右移(算术移位:

算术左移时,右端(低位)补0,左端(高位)部分舍去;右移保证符号位不改变)。

设计流程图为:

示例:

Verilog示例代码:

modulebooth_mult(product,ready,word1,word2,start,clock,reset);

parameterL_word=4;

parameterL_brc=2;

parameterAll_Ones=4'b1111;

parameterAll_Zeros=4'b0000;

output[2*L_word-1:

0]product;

outputready;

input[L_word-1:

0]word1,word2;

inputstart,clock,reset;

wireload_words,shift,add,sub,ready;

wire[L_brc-1:

0]brc;

Datapath_Boothm1(product,m0,word1,word2,load_words,shift,add,sub,clock,reset);

Controller_Boothm2(load_words,shift,add,sub,read,m0,start,clock,reset);

endmodule

//控制模块

moduleController_Booth(load_words,shift,add,sub,ready,m0,start,clock,reset);

parameterL_word=4;

parameterL_state=4;

parameterL_brc=2;

outputload_words,shift,add,sub,ready;

inputstart,clock,reset;

inputm0;

reg[L_state-1:

0]state,nextstate;

parameterS_idle=0,S_1=1,S_2=2,S_3=3,S_4=4,S_5=5,S_6=6,S_7=7,S_8=8;

regload_words,shift,add,sub;

wireready=((state==S_idle)&&!

reset)||(state==S_8);

regm0_del;

wire[L_brc-1:

0]brc={m0,m0_del};

always@(posedgeclockorposedgereset)

if(reset)state<=S_idle;elsestate<=nextstate;

always@(posedgeclockorposedgereset)

if(reset)m0_del<=0;elseif(load_words)m0_del<=0;elsem0_del<=m0;

always@(stateorstartorbrc)begin

load_words=0;shift=0;add=0;sub=0;

case(state)

S_idle:

if(start)beginload_words<=1;nextstate<=S_1;end

elsenextstate<=S_idle;

S_1:

if((brc==0)||(brc==3))beginshift=1;nextstate<=S_3;end

elseif(brc==1)beginadd=1;nextstate<=S_2;end

elseif(brc==2)beginsub=1;nextstate<=S_2;end

S_3:

if((brc==0)||(brc==3))beginshift=1;nextstate<=S_5;end

elseif(brc==1)beginadd=1;nextstate<=S_4;end

elseif(brc==2)beginsub=1;nextstate<=S_4;end

S_5:

if((brc==0)||(brc==3))beginshift=1;nextstate<=S_7;end

elseif(brc==1)beginadd=1;nextstate<=S_6;end

elseif(brc==2)beginsub=1;nextstate<=S_6;end

S_7:

if((brc==0)||(brc==3))beginshift=1;nextstate<=S_8;end

elseif(brc==1)beginadd=1;nextstate<=S_8;end

elseif(brc==2)beginsub=1;nextstate<=S_8;end

S_2:

beginshift=1;nextstate=S_3;end

S_4:

beginshift=1;nextstate=S_5;end

S_6:

beginshift=1;nextstate=S_7;end

S_8:

if(start)beginload_words=1;nextstate=S_1;end

elsenextstate=S_8;

default:

nextstate=S_idle;

endcase

end

endmodule

//数据路径模块

moduleDatapath_Booth(product,m0,word1,word2,load_words,shift,add,sub,clock,reset);

parameterL_word=4;

output[2*L_word-1:

0]product;

outputm0;

input[L_word-1:

0]word1,word2;

inputload_words,shift,add,sub,clock,reset;

reg[2*L_word-1:

0]product,multiplicand;

reg[L_word-1:

0]mult;

wirem0=mult[0];

parameterAll_Ones=4'b1111;

parameterAll_Zeros=4'b0000;

always@(posedgeclockorposedgereset)begin

if(reset)beginmult<=0;multiplicand<=0;product<=0;end

elseif(load_words)begin

if(word1[L_word-1]==0)multiplicand<=w

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > IT计算机 > 电脑基础知识

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2