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题目的一些笔记备忘


查看11道真题和解析