第9章 Verilog设计进阶
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
功能仿真波形
5.5倍半整数分频器功能仿真波形图(Quartus Ⅱ)
小数分频
可用下面的方法大致实现小数分频,即先 设计两个不同分频比的整数分频器,然后 通过控制两种分频比出现的不同次数来获 得所需要的小数分频值,从而实现平均意 义上的小数分频。
【例9.13】
8.1小数频源代码
module fdiv8_1(clk_in,rst,clk_out); input clk_in,rst; output reg clk_out; reg[3:0] cnt1,cnt2; //cnt1计分频的次数 always@(posedge clk_in or posedge rst) begin if(rst) begin cnt1<=0; cnt2<=0; clk_out<=0; end else if(cnt1<9) //9次8分频 begin if(cnt2<7) begin cnt2<=cnt2+1; clk_out<=0; end else begin cnt2<=0; cnt1<=cnt1+1; clk_out<=1; end end else begin //1次9分频 if(cnt2<8) begin cnt2<=cnt2+1; clk_out<=0; end else begin cnt2<=0; cnt1<=0; clk_out<=1; end end end endmodule
以四位乘法器为例,设置三个 寄存器MA、MB和MR,分别 存储被乘数、乘数和乘积,对 MB低位补零后循环判断,根 据判断值进行加、减和移位运 算。需注意的是两个n位数相 乘,乘积应该为2n位数。高N 位存储在MR中,低n位通过 移位移入MB。另外,进行加 减运算时需要进行相应的符号 位扩展。
(4)查找表乘法器
assign G[4]=a[4]&b[4]; assign P[4]=a[4]|b[4]; assign C[4]=G[3]|(P[3]&C[3]); assign sum[4]=G[2]^P[2]^C[2]; assign G[5]=a[5]&b[5]; assign P[5]=a[5]|b[5]; assign C[5]=G[4]|(P[4]&C[4]); assign sum[5]=G[5]^P[5]^C[5]; assign G[6]=a[6]&b[6]; assign P[6]=a[6]|b[6]; assign C[6]=G[5]|(P[5]&C[5]); assign sum[6]=G[6]^P[6]^C[6]; assign G[7]=a[7]&b[7]; assign P[7]=a[7]|b[7]; assign C[7]=G[6]|(P[6]&C[6]); assign sum[7]=G[7]^P[7]^C[7]; assign cout=G[7]|(P[7]&C[7]); endmodule
(2)数据流描述的加法器
module add_bx(cout,sum,a,b,cin); parameter WIDTH=8; input cin; output cout; input[WIDTH-1:0] a,b; output[WIDTH-1:0] sum; assign {cout,sum}=a+b+cin; endmodule
end
模13奇数分频器功能仿真波形图(Quartus Ⅱ)
【例9.12】
5.5半整数分频
module fdiv5_5(clkin,clr,clkout); input clkin,clr; output reg clkout; reg clk1; wire clk2; integer count; xor xor1(clk2,clkin,clk1); //异或门 always@(posedge clkout or negedge clr) //2分频器 begin if(~clr) begin clk1<=1'b0; end else clk1<=~clk1; end always@(posedge clk2 or negedge clr) //模5分频器 begin if(~clr) begin count<=0; clkout<=1'b0; end else if(count==5) //要改变分频器的模,只需改变count的值 begin count<=0; clkout<=1'b1; end else begin count<=count+1; clkout<=1'b0; end end endmodule
被乘数A 乘数B 部分积0 部分积1 A左移 部分积2 A左移 积P
1011 × 1101 1011 0000 01011 1011 110111 1011 10001111
4×4移位相加乘法操作示意图
8位移位相加乘法器顶层设计
8位移位相加乘法器时序仿真波形
(3)布斯乘法器
移位相加乘法器可以直接处理无符号数相 乘,但运算速度较慢而且对于有符号数相 乘运算需要附加两次原码补码转换运算。 布斯算法是一种较好的解决方法,它不仅 提高了运算效率,而且对于无符号数和有 符号数可以统一运算。
(4)流水线加法器
module adder8(cout,sum,a,b,cin,enable); input[7:0] a,b; input cin,enable; output[7:0] sum; reg[7:0] sum; output cout;reg cout; reg[3:0] tempa,tempb,firsts; reg firstc; always @(posedge enable) begin {firstc,firsts}=a[3:0]+b[3:0]+cin; tempa=a[7:4]; tempb=b[7:4]; end always @(posedge enable) begin {cout,sum[7:4]}=tempa+tempb+firstc; sum[3:0]=firsts; end endmodule
9.2 乘法器 ◆ 并行乘法器
◆ 移位相加乘法器
◆ 布斯乘法器 ◆ 查找表乘法器
(1)并行乘法器
module mult(outcome,a,b); parameter size=8; input[size:1] a,b; output[2*size:1] outcome; assign outcome=a*b; endmodule
(3) 8位超前进位加法器
module add_ahead(sum,cout,a,b,cin); input[7:0] a,b; input cin; output[7:0] sum; output cout; wire[7:0] G,P; wire[7:0] C,sum; assign G[0]=a[0]&b[0]; assign P[0]=a[0]|b[0]; assign C[0]=cin; assign sum[0]=G[0]^P[0]^C[0]; assign G[1]=a[1]&b[1]; assign P[1]=a[1]|b[1]; assign C[1]=G[0]|(P[0]&cin); assign sum[1]=G[1]^P[1]^C[1]; assign G[2]=a[2]&b[2]; assign P[2]=a[2]|b[2]; assign C[2]=G[1]|(P[1]&C[1]); assign sum[2]=G[2]^P[2]^C[2]; assign G[3]=a[3]&b[3]; assign P[3]=a[3]|b[3]; assign C[3]=G[2]|(P[2]&C[2]); assign sum[3]=G[3]^P[3]^C[3];
模7奇数分频器功能仿真波形图(Quartus Ⅱ)
【例9.11】
占空比50%的奇数分频
module count_num(reset,clk,cout); parameter NUM=13; input clk,reset; output wire cout; reg[4:0] m,n; reg cout1,cout2; assign cout=cout1|cout2; always @(posedge clk) begin if(!reset) begin cout1<=0; m<=0; end else begin if(m==NUM-1) m<=0; else m<=m+1; if(m<(NUM-1)/2) cout1<=1; else cout1<=0; end end always @(negedge clk) begin if(!reset) begin cout2<=0; n<=0; end else begin if(n==NUM-1) n<=0; else n<=n+1; if(n<(NUM-1)/2) cout2<=1; else cout2<=0; end endmodule
利用Verilog语言的乘法操作符,可很容易地 实现并行乘法器,并可由EDA综合软件自动转化 为电路网表结构
8×8并行乘法器的门级综合原理图
(2)移位相加乘法器
移位相加乘法器将乘法 变为加法实现,其设计 思路是:乘法通过逐次 移位相加实现,每次判 断乘数的最低位,若为 1则将被乘数移位相加。
占空比50%的奇数分频(模7)
module count7(reset,clk,cout); input clk,reset; output wire cout; reg[2:0] m,n; reg cout1,cout2; assign cout=cout1|cout2; //两个计数器的输出相或 always @(posedge clk) begin if(!reset) begin cout1<=0; m<=0; end else begin if(m==6) m<=0; else m<=m+1; if(m<3) cout1<=1; else cout1<=0; end end always @(negedge clk) begin if(!reset) begin cout2<=0; n<=0; end else begin if(n==6) n<=0; else n<=n+1; if(n<3) cout2<=1; else cout2<=0; end end endmodule
9.3 奇数分频与小数分频
(1)奇数分频
在实际中我们经常会遇到这样的问题,需要 进行奇数次分频,同时又要得到占空比是 50%的方波波形。 可采用如下方法:用两个计数器,一个由输 入时钟上升沿触发,一个由输入时钟下降沿 触发,最后将两个计数器的输出相或,即可 得到占空比为50%的方波波形。
【例9.10】
查找表乘法器将乘积直接存放在存储器中,将操作数 (乘数和被乘数)作为地址访问存储器,得到的输出 数据就是乘法运算的结果。 查找表方式的乘法器速度只局限于所使用存储器的存 取速度。但由于查找表规模随操作数位数增加而迅速 增大,因此如用于实现位数宽的乘法操作,需要 FPGA器件具有较大的片内存储器模块。比如,要实 现8×8乘法,要求存储器的地址位宽为16位,字长 为16位,即存储器大小为1M比特。
第9章 Verilog设计进阶
9.1 加法器设计
◆ 级连加法器
◆ 数据流描述的加法器
◆ 超前进位加法器
◆ 流水线加法器
(1)级连加法器
a[0] b[0] a[1] b[1] a[2] b[2] a[7] b[7]
cin
1位 全加器
cin[1]
1位 全加器
cin[2]
1位 全加器
cin[7]
Fra Baidu bibliotek
1位 全加器
cout
sum[0]
sum[1]
sum[2]
sum[7]
8位级连加法器代码
module add_jl(sum,cout,a,b,cin); input[7:0] a,b; input cin; output[7:0] sum; output cout; full_add1 f0(a[0],b[0],cin,sum[0],cin1); full_add1 f1(a[1],b[1],cin1,sum[1],cin2); full_add1 f2(a[2],b[2],cin2,sum[2],cin3); full_add1 f3(a[3],b[3],cin3,sum[3],cin4); full_add1 f4(a[4],b[4],cin4,sum[4],cin5); full_add1 f5(a[5],b[5],cin5,sum[5],cin6); full_add1 f6(a[6],b[6],cin6,sum[6],cin7); full_add1 f7(a[7],b[7],cin7,sum[7],cout); endmodule