
写在前面 本系列博客记录牛客网刷题记录 日拱一卒功不唐捐目录题目描述题目分析Verilog 代码testbench 代码仿真结果题目描述已知d为一个8位数请在每个时钟周期分别输出该数乘1/3/7/8,并输出一个信号通知此时刻输入的d有效d给出的信号的上升沿表示写入有效信号示意图波形示意图输入描述输入信号dclkrst类型wirewirewire在testbench中clk为周期 5ns 的时钟rst 为低电平复位输出描述输出信号input_grantout类型regreg题目分析从题目的要求和时序上进行分析复位信号拉高之后对接收到的数据进行计算输出依次输出乘1、乘3、乘7、乘8的数值并且在第一个乘1的输出值同步拉高输出信号 input_grant同时需要注意的是在输入数据过于密集的时候输入的数据是会被忽略的也可以看到 input_grant 信号是每 4 个时钟周期拉高一次因此可以申明一个计数器用于判定输出值 out 和 有效信号 input_grant。移位运算Verilog 中移位操作符号有2种分别是 “” 左移位运算符和 “” 右移位运算符。格式如下anan。其中a代表要移位的操作数n代表要移几位。两种运算方式都用0来填补移出的空位。移位操作符对左边的操作数进行向左或向右的位移位操作第二个操作数移位位数是无符号数遵循的操作规律是“左移时先补后移右移时先移后补”。在进行移位运算时应当注意移位前后变量的位数。如果操作数已经定义了位宽则进行移位后操作数改变但是其位宽不变。Verilog 代码/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ // Author : Linest-5 // File : multi_sel.v // Create : 2022-10-07 18:59:24 // Revise : 2022-10-07 19:58:16 // Module Name : multi_sel // Description : 选择乘积数输出 // Editor : sublime text3, tab size (4) /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ timescale 1ns/1ns module multi_sel( input [7:0] d , input clk, input rst, //复位低有效 output reg input_grant, output reg [10:0] out ); //*************code***********// reg [7:0] d_reg; reg [1:0] cnt; //循环计数器 always (posedge clk or negedge rst) begin if (!rst) begin cnt d0; end else begin cnt cnt d1; end end //每当合适时间数据来临时将数据寄存 always (posedge clk or negedge rst) begin if (!rst) begin d_reg d0; end else if (cnt d0) begin d_reg d; end else begin d_reg d_reg; end end //根据计数值输出相应的数值 always (posedge clk or negedge rst) begin if (!rst) begin out d0; end else if (cnt d0) begin out d; //乘1 end else if (cnt d1) begin out (d_reg 2) - d_reg; //乘3 end else if (cnt d2) begin out (d_reg 3) - d_reg; //乘7 end else if (cnt d3) begin out (d_reg 3); //乘8 end else begin out out; end end //输出有效数据标志信号 always (posedge clk or negedge rst) begin if (!rst) begin input_grant d0; end else if (cnt d0) begin input_grant d1; end else begin input_grant d0; end end //*************code***********// endmoduletestbench 代码/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ // Author : Linest-5 // File : tb_multi_sel.v // Create : 2022-10-07 19:58:57 // Revise : 2022-10-07 20:22:50 // Module Name : // Description : // Editor : sublime text3, tab size (4) /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ timescale 1ns/1ns module tb_multi_sel(); reg clk; reg rst; //复位低有效 reg [7:0] d; wire [10:0] out; wire input_grant; initial begin clk d1; rst d0; #50 rst d1; end initial begin d d23; (posedge rst); (posedge clk); (posedge clk); (posedge clk); (posedge clk); d d7; (posedge clk); d d6; (posedge clk); d d12; (posedge clk); (posedge clk); (posedge clk); (posedge clk); (posedge clk); (posedge clk); (posedge clk); (posedge clk); d d4; (posedge clk); (posedge clk); d d9; (posedge clk); (posedge clk); (posedge clk); (posedge clk); (posedge clk); d d12; #100 $finish; end always #5 clk ~clk; multi_sel inst_multi_sel ( .d(d), .clk(clk), .rst(rst), .input_grant(input_grant), .out(out) ); //verdi initial begin $fsdbDumpfile(tb_multi_sel.fsdb); $fsdbDumpvars(0); end endmodule仿真结果电路结构图仿真波形图在 testbench 中设计了输入几组数据其中有些数据会输入的比较密集仿真波形中也能很直观的看出。