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
|