打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
【EDA】实验4:常用元件的 Verilog RTL 代码设计

多路选择器

一.实验内容

1.做一个4选1的多路选择器,并进行波形仿真。
2.将4选1多路选择器同2选1多路选择器对比,观察资源消耗的变化。

二.实验步骤

1.创建项目
创建项目的过程与前几篇文章相同,不再赘述。

2.添加Verilog HDL文件

3.编写Verilog HDL代码
具体代码如下:

// module  top, 选择器(mux)的代码,module top(  IN0       ,   // input 1  IN1       ,   // input 2  IN2       ,   // input 3  IN3       ,   // input 4  SEL       ,   // select   OUT       );  // out data  input [15:0] IN0, IN1, IN2, IN3;// 选择器的输入数据信号input [1:0] SEL;              // 通道选通的控制信号output[15:0] OUT;     // 选择器的输入数据信号reg   [15:0] OUT;// 生成组合逻辑的代码always @ (IN0 or IN1 or IN2 or IN3 or SEL) begin  if(SEL==0) // SEL为0 选择输入0    OUT = IN0;  else  if(SEL==1)  // SEL为1 选择输入1    OUT = IN1;  else  if(SEL==2)  // SEL为2 选择输入2	OUT = IN2;  else  if(SEL==3)  // SEL为3 选择输入3	OUT = IN3;endendmodule// endmodule top

4.编译代码

5.添加并配置Vector Waveform File
添加Vector Waveform文件并配置仿真输入波形的方法在之前的文章已说明过了,此处直接展示仿真的结果。


从仿真波形中可以看到:当SEL端的信号变化时,输出端会选择相应的输入信号进行输出。

6.4选1多路选择器的RTL结构
对于Quartus工具,可以按照如下路径找到RTL Viewer:Tools -> Netlist Viewer -> RTL Viewer
本实验代码生成的RTL结构如下图:
第一页:


第二页:

7.2选1多路选择器的RTL结构


8.两种多路选择器的资源消耗对比
2选1多路选择器:

4选1多路选择器:

可见4选1多路选择器相比2选1多路选择器消耗更大的硬件资源。

交叉开关

一.实验内容

1.编写一个4X4路交叉开关的Verilog代码,然后编译,进行波形仿真。
2.观察RTL View,比较2x2路交叉开关与4x4路交叉开关之间消耗资源的区别。

二.实验步骤

1.编写Verilog HDL代码

// module  top, a 4x4 crossbar switch circuitmodule top(  IN0       ,   // input 1  IN1       ,   // input 2  IN2       ,   // input 3  IN3       ,   // input 4  SEL0      ,   // select the output0 source   SEL1      ,   // select the output1 source   SEL2      ,   // select the output2 source   SEL3      ,   // select the output3 source   OUT0      ,   // output data 0  OUT1      ,   // output data 1  OUT2      ,   // output data 2  OUT3      );  // output data 3input [15:0] IN0, IN1, IN2, IN3;input [1:0] SEL0, SEL1, SEL2, SEL3;output[15:0] OUT0, OUT1, OUT2, OUT3;reg   [15:0] OUT0, OUT1, OUT2, OUT3;// get the OUT0always @ (IN0 or IN1 or IN2 or IN3 or SEL0) begin  if(SEL0==0)    OUT0 = IN0;  else if(SEL0==1)    OUT0 = IN1;  else if(SEL0==2)    OUT0 = IN2;  else if(SEL0==3)    OUT0 = IN3;end// get the OUT1always @ (IN0 or IN1 or IN2 or IN3 or SEL1) begin  if(SEL1==0)    OUT1 = IN0;  else if(SEL1==1)    OUT1 = IN1;  else if(SEL1==2)    OUT1 = IN2;  else if(SEL1==3)    OUT1 = IN3;end// get the OUT2always @ (IN0 or IN1 or IN2 or IN3 or SEL2) begin  if(SEL2==0)    OUT2 = IN0;  else if(SEL2==1)    OUT2 = IN1;  else if(SEL2==2)    OUT2 = IN2;  else if(SEL2==3)    OUT2 = IN3;end// get the OUT3always @ (IN0 or IN1 or IN2 or IN3 or SEL3) begin  if(SEL3==0)    OUT3 = IN0;  else if(SEL3==1)    OUT3 = IN1;  else if(SEL3==2)    OUT3 = IN2;  else if(SEL3==3)    OUT3 = IN3;endendmodule// endmodule top

2.波形仿真

3.查看4×4交叉开关的RTL结构
第一页:


第二页:

第三页:

第四页:

第五页:

第六页:

4.查看2×2交叉开关的RTL结构*


5.两种交叉开关的资源消耗对比
2×2交叉开关的资源消耗:

4×4交叉开关的资源消耗:

可见,4×4交叉开关的逻辑单元消耗是2×2交叉开关的4倍。

优先编码器

一.实验内容

1.编写一个8输入的优先编码器,然后编译,查看RTL View。

二.实验步骤

1.编写Verilog HDL代码

// module top, 8 input priority encoder with zero input checkmodule top(  IN        ,   // input    OUT       );  // output input [7:0] IN;output[3:0] OUT;reg   [3:0] OUT;// get the OUTalways @ (IN) begin   if(IN[7])       // 第一优先级     OUT = 4'b111;   else if(IN[6])  // 第二优先级     OUT = 4'b110;   else if(IN[5])  // 第三优先级     OUT = 4'b101;   else if(IN[4])  // 第四优先级     OUT = 4'b100;   else if(IN[3])  // 第五优先级     OUT = 4'b011;   else if(IN[2])  // 第六优先级     OUT = 4'b010;   else if(IN[1])  // 第七优先级     OUT = 4'b001;   else if(IN[0])  // 第八优先级     OUT = 4'b000;   else            // 什么都没有检测到     OUT = 4'b1111; // 输出值可自定义,不和上面的输出值混淆即可endendmodule

2.波形仿真

3.查看RTL View

多路译码器

一.实验内容

1.编写一个4-16的译码器,编译,仿真。
2.查看RTL View,并和3-8译码器对比资源开销。

二.实验步骤

1.编写Verilog HDL代码

// module top, 4-16 decodermodule top(  IN        ,   // input    OUT       );  // output input [3:0] IN;output[15:0] OUT;reg   [15:0] OUT;// get the OUTalways @ (IN) begin  case(IN)    4'b0000: OUT = 16'b0000_0000_0000_0001;    4'b0001: OUT = 16'b0000_0000_0000_0010;    4'b0010: OUT = 16'b0000_0000_0000_0100;    4'b0011: OUT = 16'b0000_0000_0000_1000;    4'b0100: OUT = 16'b0000_0000_0001_0000;    4'b0101: OUT = 16'b0000_0000_0010_0000;    4'b0110: OUT = 16'b0000_0000_0100_0000;    4'b0111: OUT = 16'b0000_0000_1000_0000;    4'b1000: OUT = 16'b0000_0001_0000_0000;    4'b1001: OUT = 16'b0000_0010_0000_0000;    4'b1010: OUT = 16'b0000_0100_0000_0000;    4'b1011: OUT = 16'b0000_1000_0000_0000;    4'b1100: OUT = 16'b0001_0000_0000_0000;    4'b1101: OUT = 16'b0010_0000_0000_0000;    4'b1110: OUT = 16'b0100_0000_0000_0000;    4'b1111: OUT = 16'b1000_0000_0000_0000;    //  full case 不需要写default,否则一定要有default  endcaseendendmodule

2.波形仿真

3.查看RTL View
4-16译码器:

3-8译码器:

4.对比资源开销
3-8译码器:


4-16译码器:

4-16译码器的资源消耗约为3-8译码器的2倍。

加法器

无符号加法器

一.实验内容

1.把加法器的输入信号和输出信号都改成4比特位宽,编译,波形仿真。观察输出结果,说出输出和输入的对应关系。
2.把加法器的输入信号改成8比特位宽,编译,波形仿真。观察加法器的输出延迟,和4比特输入位宽的情况对比。

二.实验步骤

1.编写Verilog HDL代码

module top(  IN1   ,  IN2   ,  OUT   );input[3:0] IN1, IN2;output[3:0] OUT;reg[3:0] OUT;always@(IN1 or IN2) begin // 生成组合逻辑的always 块  OUT = IN1 + IN2;endendmodule 

2.仿真波形


由上图可知,当加法器的输入信号和输出信号位宽相同时加法器得到的结果可能会丢失最高位的进位,即所得结果溢出,导致计算结果出错。当最高位无进位时输出等于两个输入的和,而当最高位有进位时则输出比两个输入的和小16(24)。

3.输入信号为8位宽的加法器的Verilog HDL代码

module top(  IN1   ,  IN2   ,  OUT   );input[7:0] IN1, IN2;output[8:0] OUT;reg[8:0] OUT;always@(IN1 or IN2) begin // 生成组合逻辑的always 块  OUT = IN1 + IN2;endendmodule 

4.8位宽加法器仿真波形


从以上两张波形图可以看出4位宽加法器和8位宽加法器的输出延迟差别不大,基本都在8ns左右。

补码加法器

一.实验内容

1.把加法器的输出信号改成4比特位宽,编译,波形仿真。观察输出结果,观察输出结果在什么时候是正确的?
2. 把加法器的输入信号改成8比特位宽,编译,波形仿真。观察加法器的输出延迟,和4比特输入位宽的情况对比。

二.实验步骤

1.编写4比特位宽输出加法器的Verilog HDL代码

module top(  IN1   ,  IN2   ,  OUT   );input signed [3:0] IN1, IN2;output signed [3:0] OUT;reg signed [3:0] OUT;always@(IN1 or IN2) begin // 生成组合逻辑的always 块  OUT = IN1 + IN2;endendmodule

2.仿真结果波形


从仿真结果可知,当两个输入信号的和大于7或小于-8时计算结果会出错,这是由于次高位进位使得符号位变化导致的。

3.编写8比特位宽输出加法器的Verilog HDL代码

module top(  IN1   ,  IN2   ,  OUT   );input signed [7:0] IN1, IN2;output signed [8:0] OUT;reg signed [8:0] OUT;always@(IN1 or IN2) begin // 生成组合逻辑的always 块  OUT = IN1 + IN2;endendmodule

4.仿真结果波形


由仿真波形可知,4位补码加法器和8位补码加法器的延迟时间相差不多,基本都是8ns。

带流水线的加法器

一.实验内容

1.不改变流水线的级数,把加法器的输入信号改成8比特位宽,编译,波形仿真,和不带流水线的情况对比一下,你有什么结论?
2.在8比特输入位宽的情况下,在输入上再添加一级流水线,观察编译和仿真的结果,你有什么结论?

二.实验步骤

1.编写8位输入带一级流水线的加法器的Verilog HDL代码

module top(  IN1   ,  IN2   ,  CLK   ,  OUT   );input  [7:0] IN1, IN2;input CLK;output  [8:0] OUT;reg [7:0] in1_d1R, in2_d1R;reg  [8:0] adder_out, OUT;always@(posedge CLK) begin // 生成D触发器的always块  in1_d1R <= IN1;  in2_d1R <= IN2;  OUT     <= adder_out;endalways@(in1_d1R or in2_d1R) begin // 生成组合逻辑的always 块  adder_out = in1_d1R + in2_d1R;endendmodule 

2.仿真结果波形


带有流水线的加法器相较于没有流水线的加法器拥有更短的毛刺,但输出延时更长。

3.RTL View


4.编写8位输入带两级级流水线的加法器的Verilog HDL代码

module top(  IN1   ,  IN2   ,  CLK   ,  OUT   );input  [7:0] IN1, IN2;input CLK;output  [8:0] OUT;reg [7:0] in1_d1R, in2_d1R, in1_d2R, in2_d2R;reg  [8:0] adder_out, OUT;always@(posedge CLK) begin // 生成D触发器的always块  in1_d1R <= IN1;  in1_d2R <= in1_d1R;  in2_d1R <= IN2;  in2_d2R <= in2_d1R;  OUT     <= adder_out;endalways@(in1_d2R or in2_d2R) begin // 生成组合逻辑的always块  adder_out = in1_d2R + in2_d2R;endendmodule 

5.仿真结果波形


增加一级流水线后使得毛刺的时间长度进一步减小,但是输出延迟变得更大。

6.RTL View

乘法器

一.实验内容

1.改变乘法器的输入位宽为8比特,编译,波形仿真,观察信号毛刺的时间长度。
2.选一款没有硬件乘法器的FPGA芯片(例如Cyclone EP1C6)对比8比特的乘法器和加法器两者编译之后的资源开销(Logic Cell的数目)
3.编写一个输入和输出都有D触发器的流水线乘法器代码,编译后波形仿真,观察组合逻辑延迟和毛刺的时间,和不带流水线的情况下对比。

二.实验步骤

1.编写8位输入的乘法器的Verilog HDL代码

////////////////////  有符号的2补码乘法器  /////////////////////////module top(  IN1   ,  IN2   ,  OUT   ); input signed[7:0] IN1, IN2; output signed [15:0] OUT; reg signed[15:0] OUT; always@(IN1 or IN2) begin // 生成组合逻辑的always 块  OUT = IN1 * IN2;endendmodule

2.仿真结果波形


从图中可得,毛刺信号约占4ns。

3.没有硬件乘法器的FPGA芯片的8比特加法器和乘法器的资源开销对比
加法器资源开销:


乘法器硬件开销:

由上图可见,乘法器相较加法器更加消耗资源。

4.输入和输出都有D触发器的流水线乘法器的Verilog HDL代码

////////////////////  带有流水线的补码乘法器  /////////////////////////module top(  IN1   ,  IN2   ,  CLK   ,  OUT   ); input signed[7:0] IN1, IN2; input CLK; output signed [15:0] OUT; reg signed[15:0] OUT; reg signed[7:0] in1_d1R, in2_d1R; reg signed[15:0] mul_out;always@(posedge CLK) begin // 生成D触发器的always块  in1_d1R <= IN1;  in2_d1R <= IN2;  OUT     <= mul_out;end always@(in1_d1R or in2_d1R) begin // 生成组合逻辑的always 块  mul_out = in1_d1R * in2_d1R;endendmodule 

5.仿真结果波形


有仿真波形可得:带有流水线的乘法器的组合逻辑延迟和毛刺的时间约为2ns,相比不带流水线的乘法器要减少了一半。

计数器

一.实验内容

1.设计一个最简单的计数器,只有一个CLK输入和一个Overflow输出,当计数到最大值的时钟周期CLK输出1
2.设计复杂的计数器,和本例相似,带有多种信号,其中同步清零CLR的优先级最高,使能EN次之,LOAD最低。

二.实验步骤

1.编写简单计数器的Verilog HDL代码

//////////////////// 计数器代码  /////////////////////////module top(  CLK   , // 时钟,上升沿有效  OV    );// 计数溢出信号,计数值为最大值时该信号为1input CLK ;output OV;   reg OV;reg [3:0] CNTVAL, cnt_next;// 电路编译参数,最大计数值parameter CNT_MAX_VAL = 9;// 组合逻辑,生成cnt_nextalways @(CNTVAL) begin  if(CNTVAL < CNT_MAX_VAL) begin // 未计数到最大值, 下一值加1    cnt_next = CNTVAL + 1'b1;  end  else begin // 计数到最大值,下一计数值为0    cnt_next = 0;  endend// 时序逻辑 更新下一时钟周期的计数值// CNTVAL 会被编译为D触发器always @ (posedge CLK) begin    CNTVAL <= cnt_next;end// 组合逻辑,生成OValways @ (CNTVAL) begin  if(CNTVAL == CNT_MAX_VAL)     OV = 1;  else    OV = 0;endendmodule

2.仿真结果波形


如波形图所示,当经过9个周期的时钟信号后OV端口输出一个高电平的溢出信号。

3.编写复杂计数器的Verilog HDL代码

//////////////////// 计数�%
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
FPGA开发流程1(详述每一环节的物理含义和实现目标)
QUICKLOGIC QUICKWORKS
ASIC设计学习总结之工具及书籍文档
Quartus II调用modelsim无缝仿真
ModelSim和QuestaSim功能简介及应用
功能仿真和时序仿真
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服