Verilog写题笔记4-------- #移位运算与乘法#
移位运算与乘法
https://www.nowcoder.com/practice/1dd22852bcac42ce8f781737f84a3272
输入有三个:
1、8位数据d
2、时钟clk
3、复位信号rst
输出有两个:
1、输出指示input_grant
2、10位输出数据out
题意是这样的:
在每个时钟上升沿,输出d的1倍,3倍,7倍和8倍结果,同时在输出1倍结果时,同时将input_grant置高一个时钟周期,其他时刻置0。注意:输出这四个结果需要4个时钟周期,如果在这四个时钟内
输入d改变,则无视新的d信号,仍然输出原来的结果。
从这个波形图就可以看到,当d变成128,但是out仍然输出的是6的倍数,换言之,模块只会在输出一倍结果时采集输入信号。
编程思路:
从out的波形入手,out一直在以四个时钟周期做循环输出。所以模块的核心是一个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***********// parameter flag_max = 2'd3; //定义4计数器的最大值 reg [1:0] flag; //计数器变量 reg [10:0] data_reg; //存储输入变量 always@(posedge clk or negedge rst) //4计数器 if(rst == 1'b0) flag <= 2'd0; else if(flag == flag_max) flag <= 2'd0; else flag <= flag + 1'b1; always@(posedge clk or negedge rst) //根据计数器的不同值输出不同的结果 if(rst == 1'b0) begin out <= 10'd0; input_grant <= 1'b0; end else case(flag) 2'd0:begin //计数器为0:input_grant置高,输出为1倍d,同时储存d的值到变量data_reg以备接下来的计算 input_grant <= 1'b1; out <= d; data_reg <= d; end 2'd1:begin //计数器为1:input_grant置0,输出为3倍d input_grant <= 1'b0; out <= 3*data_reg; end 2'd2:begin //计数器为2:input_grant置0,输出为7倍d input_grant <= 1'b0; out <= 7*data_reg; end 2'd3:begin //计数器为3:input_grant置0,输出为8倍d input_grant <= 1'b0; out <= 8*data_reg; end default:begin //case最后加default是良好的编程习惯 out <= 10'd0; input_grant <= 1'b0; end endcase //*************code***********// endmodule
verilog写题笔记 文章被收录于专栏
写Verilog题目的一些笔记备忘