:::info
【分析】
- 根据要求,在sel = 0的时候输入才是有效的,其他时刻的输入是没用的,因此必须声明一个reg类型来对输入进行暂存(与移位运算和乘法题目相同);
- 位分割;
:::
1. Verilog代码实现
``verilogtimescale 1ns/1ns module data_cal( input clk, input rst, input [15:0] d, input [1:0] sel, output [4:0] out, output validout ); //**code*// reg [15:0] d_reg; reg [4:0] out_reg; reg validout_reg; always@(posedge clk or negedge rst) begin if(!rst) begin out_reg <= 5’b0; validout_reg <= 1’b0; end else begin case(sel)
endcase end end assign validout = validout_reg; assign out = out_reg; //**code*// endmodule // Method2 reg [15:0] d_reg; wire [3:0] d0; wire [3:0] d1; wire [3:0] d2; wire [3:0] d3; assign d0 = d_reg[3:0]; assign d1 = d_reg[7:4]; assign d2 = d_reg[11:8]; assign d3 = d_reg[15:12]; reg [4:0] out_reg; //**code*// endmodule2'b00 : beginvalidout_reg <= 1'b0;d_reg <= d;out_reg <= 5'b0;end2'b01 : beginvalidout_reg <= 1'b1;out_reg <= d_reg[3:0] + d_reg[7:4];end2'b10 : beginvalidout_reg <= 1'b1;out_reg <= d_reg[3:0] + d_reg[11:8];end2'b11 : beginvalidout_reg <= 1'b1;out_reg <= d_reg[3:0] + d_reg[15:12];enddefault : beginvalidout_reg <= 1'b0;out_reg <= 5'b0;end
> 过程中遇到的问题:> 1. 复位的时候是只对output信号进行复位;> 1. always块中必须使用reg类型,因此必须声明reg类型的变量来进行存放并在之后使用assign连接;> 1. 使用第二种方法对寄存器提前进行位拆分,在以后的大型逻辑电路中可以更方便对照。<a name="yUE7Z"></a># 2. Testbench自测模式:::info`timescale 1ns/1ns:<br />前面的1ns指的是时间的间隔:比如 #5就是5ns;<br />后面的1ns指的是时间的精度,设置的越小仿真就越慢。:::```verilog`timescale 1ns/1nsmodule data_cal_tb;bit clk;bit rst;reg [15:0] d;reg [1:0] sel;wire [4:0] out;wire validout;data_cal dut(.clk(clk),.rst(rst),.d(d),.sel(sel),.out(out),.validout(validout));initial begin : gen_clkforever #5 clk <= !clk;endinitial beginclk = 0;rst = 0;d = 16'd0;sel = 2'b00;#30;rst = 1;sel = 2'b00;d = 16'b1000_0100_0010_0001;#10;sel = 2'b01;d = 16'b1111_1111_1111_1111;#10;sel = 2'b10;d = 16'b1000_0000_0000_0000;#10;sel = 2'b11;d = 16'b1000_0000_0000_0000;#10;sel = 2'b00;d = 16'b1000_0100_0010_0001;#30;$finish();endendmodule

将data_cal.v和tb.sv文件放在Questasim中编译并仿真,观察tb中信号的波形,结果如上:
- 在SEL为0的时候输入有效,输入的值是十六进制的8421并保存在寄存器中;
- 在SEL为1的时候输出低8位相加,相加以后的结果就是3。
在写tb的时候需要注意:
- 功能方面需要和设计文件保持一致,从复位以后的值开始。
- 在rst拉高以后其他信号有效,此时观察序列运算后的结果。
