1. 题目

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


2. 解析

2.1 移位运算实现乘法


2.2 题目波形分析进行寄存

如下图所示的红框和绿框内的数据非常关键。如果对输入的d在连续的4个时钟周期内分别进行d*1、d*3、d*7和d*8操作,那么当出现如红框内所示的6时,这个数据只持续了1个clk,显然这时候做的操作是:

6*1、128*3、129*7、129*8,和预期不符。

如何保证做的移位乘法都是基于第一次的输入呢?

答案:加一个寄存器,对输入寄存

d_reg <= d;

后面的*3、*7、*8均对d_reg操作,执行完后再根据输入d更新d_reg。

 

3. 代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
`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 [1:0] count;    // 0 1 2 3
    always @ (posedge clk&nbs***bsp;negedge rst)
        begin
            if(~rst) begin
                count <= 2'b0;
            end
            else begin
                count <= count + 1'b1;
            end
        end
 
    // FSM
    reg [7:0] d_reg;
        always @ (posedge clk&nbs***bsp;negedge rst)
        begin
            if(~rst) begin
                out <= 11'b0;
                input_grant <= 1'b0;
                d_reg <= 8'b0;
            end
            else begin
                case( count )
                    2'b00 : begin
                        out <= d;
                        d_reg <= d;
                        input_grant <= 1'b1;
                    end
                    2'b01 : begin
                        out <= d_reg + {d_reg, 1'b0};    // *1 + *2
                        input_grant <= 1'b0;
                    end
                    2'b10 : begin
                        out <= d_reg + {d_reg, 1'b0} + {d_reg, 2'b0};
                        input_grant <= 1'b0;
                    end
                    2'b11 : begin
                        out <= {d_reg, 3'b0};
                        input_grant <= 1'b0;
                    end
                    default : begin
                        out <= d;
                        input_grant <= 1'b0;
                    end
                endcase
            end
        end
//*************code***********//
endmodule