![](https://csdnimg.cn/release/download_crawler_static/86288070/bg4.jpg)
二、alu的改进
为了支持乘除法指令,需要实现多周期的:乘法器 multiplier ,除法器 divider ;两种种运算都采用
有限状态机控制的方式,通过竖式计算的逻辑实现电路计算;( multiplier.sv 和 divider.sv 为两个
参考的32位多周期乘除法器)
假设两种运算器都实现后,alu中应改进为时序逻辑并始终连接运算器,以乘法器为例,
乘法器的输入输出端口如下:
alu的乘法运算逻辑如下:
alu中判断是否为乘法操作,如果命中,则把乘法器有效信号置为1,发起一次乘法运算请求;
无论alu中的运算是什么种类, multiplier 应始终连接两个操作数;
乘法操作时, multiplier 接收到 valid 信号,开始进行乘法计算;
alu中始终阻塞,当 multiplier 的握手信号 done 为1时,说明计算结果已有效,在下一周期完成
一次握手;
完成握手后运算结束,alu进行一次握手,开始处理下一条指令;
综上,alu应该由组合逻辑调整为时序逻辑,接收同步时钟信号,且乘法器的线路逻辑如下:
module multiplier (
// 输入端口:时钟信号,复位信号,有效信号,符号计算信号与两个操作数
input logic clk, reset, valid, sign,
input u64 srca, srcb,
// 输出端口:计算结束的握手信号与计算结果
output logic done,
output u64 result
);
1
2
3
4
5
6
7
8
module alu(
// ...
);
// 处理操作数
// ...
// 进行计算的组合逻辑
always_comb begin
unique case(alu_func)
// 其他运算...
// 乘法运算,乘法运算置位,开始运算
MUL : mul_valid = 1'b1;
endcase
end
// 处理结果
// ...
// 对外生成阻塞信号,运算器未计算结束时
assign stall = (mul_valid || div_valid || mod_valid) && ~done;
// 增加时序处理握手
always_ff(posedge clk) begin
// 上次运算结束,且下次运算不是乘法,则把mul_valid置为0;
if(done && (alu_func != MUL) ) begin
mul_valid = 1'b0;
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