题意整理
1、在硬件中进行乘除法运算是比较消耗资源的一种方法,想要在不影响延迟并尽量减少资源消耗,必须从硬件的特点上进行设计。根据寄存器的原理,由于是二进制,所以进位和退位为x2或者/2,同样除7可以使用进位3然后减去本身的做法,这样就将乘除法运算转化为位运算,这是一种比较简单的整数运算处理。
2、 需要给出一个计数器的状态机,注意d输入不是随时有效的,只有在cnt计数为0的那个时钟沿,d输入有效,因此需要设计一个寄存器din,在cnt为0时候锁存d的值
题解主体
根据题意分析,可以得到状态转换:
设输入为d,计数器为cnt
移位运算逻辑:
位运算 |
|
1 |
d |
3 |
(din<<2)-din |
7 |
(din<<3)-din |
8 |
(din<<3) |
状态机逻辑:
cnt |
out |
input_grant |
0 |
直接输出d,并寄存d的值为din |
1 |
1 |
(din<<2)-din |
0 |
2 |
(din<<3)-din |
0 |
3 |
(din<<3) |
0 |
将电路转换成Verilog代码描述如下
reg [1:0]cnt;
reg [7:0]din;
always@(posedge clk or negedge rst) begin
if(!rst) begin
cnt <= 0;
out <= 0;
input_grant <= 0;
din <= 0;
end
else begin
cnt <= cnt+1;
case (cnt)
0: begin
din <= d;
input_grant <= 1;
out <= d;
end
1: begin
input_grant <= 0;
out <= (din<<2)-din;
end
2: begin
input_grant <= 0;
out <= (din<<3)-din;
end
3: begin
input_grant <= 0;
out <= (din<<3);
end
endcase
end
end
因此实现方式为如下的电路,综合得到:
参考答案
`timescale 1ns/1ns module multi_sel( input [7:0]d , input clk, input rst, output reg input_grant, output reg [10:0]out ); reg [1:0]cnt; reg [7:0]din; always@(posedge clk or negedge rst) begin if(!rst) begin cnt <= 0; out <= 0; input_grant <= 0; din <= 0; end else begin cnt <= cnt+1; case (cnt) 0: begin din <= d; input_grant <= 1; out <= d; end 1: begin input_grant <= 0; out <= (din<<2)-din; end 2: begin input_grant <= 0; out <= (din<<3)-din; end 3: begin input_grant <= 0; out <= (din<<3); end endcase end end endmodule