数字IC设计、验证、FPGA笔试必会 - Verilog经典习题 (四)移位运算与乘法

时间:2023-01-13 13:55:18

数字IC设计、验证、FPGA笔试必会 - Verilog经典习题 (四)移位运算与乘法


????声明:
????博主主页:王_嘻嘻的CSDN博客
????未经作者允许,禁止转载
????系列专栏:牛客Verilog习题集
????推荐一个IC、FPGA新手入门的好网站:????快 点 击 进 入 学 习 吧


  继续整理牛客网经典Verilog习题讲解,牛客网里除了最新的Verilog题库还有其它领域的经典笔试、面试题,大家快和我一起刷起来吧 点 击 跳 转



题目


已知d为一个8位数,请在每个时钟周期分别输出该数乘1/3/7/8,并输出一个信号通知此时刻输入的d有效(d给出的信号的上升沿表示写入有效)


数字IC设计、验证、FPGA笔试必会 - Verilog经典习题 (四)移位运算与乘法


分析:

  本题理解起来应该不难,主要是练习时序电路的控制。需要注意的是out需要连续输出第一拍采集数据的1/3/7/8倍,而在这4拍的输出中,所有的输入是忽略的。根据clk上升沿虚线,可以看出,对输入采样的第一拍就开始out有效

  例如d输入128时,还处于第三个数据的1倍输出。




题解:

  在完成这题时,可能很多新手分析不清时序,其实我们只需要抓住时序的重点,再围绕展开即可
  本题的重点其实在于连续输出4拍数据,且连续不断的输出;至于哪一拍输出grant_vld或是每一拍数据怎么处理都是后话了。

  • 那么是否可以采用一个计数器来记录节拍呢,有了这个节拍,输出数据就好处理了;
  • 如下列代码所示,如果cnt(计数器)复位值为0,那么复位释放后,第一拍有效时cnt=1,所以cnt的周期为1、2、3、0的循环
  • 所以grant_vld永远在cnt=1时有效即可;
  • 并根据cnt值的区别进行不同的数据操作;
  • 而为了忽略输入信号中途改变的影响,需要在每次周期结束后,采样输入d,作为下一周期的数据。

注意:虽然题目描述的是乘法,但其实只有3、7不是2的幂次,且3=4-1,7=8-1。完全可以通过移位加减来完成,不需要使用更费资源的乘法,当然如果倍数过于复杂,采用乘法也是不错的,hhhhh。


`timescale 1ns/1ns
module multi_sel(
input [7:0]d ,
input  clk,
input  rst,
output input_grant,
output reg [10:0]out
);
//*************code***********//
reg [1:0]   cnt;   //用来计数连续输出的4次数据
reg [7:0]   d_tmp; //第一拍数据采集并保存

always @(posedge clk or negedge rst)begin
    if(!rst)
        d_tmp[7:0] <= 8'b0;
    else if(cnt[1:0]==2'b00)
        d_tmp[7:0] <= d[7:0];
end

always @(posedge clk or negedge rst)begin  //由于复位为0,所以input_grant有效在cnt=1时,如果需要在cnt=0时,可以自行调整复位值
    if(!rst)
        cnt[1:0] <= 2'b0;
    else
        cnt[1:0] <= cnt[1:0] + 2'b1;
end

assign input_grant = cnt[1:0]==2'b01;

always @(*)begin
    case(cnt[1:0])
        2'b01: out[10:0] <= d_tmp[7:0];
        2'b10: out[10:0] <= (d_tmp[7:0]<<2'd2) - d_tmp[7:0];
        2'b11: out[10:0] <= (d_tmp[7:0]<<2'd3) - d_tmp[7:0];
        2'b00: out[10:0] <= d_tmp[7:0]<<2'd3;
    endcase

end

//*************code***********//
endmodule