mul指令
LoongArch32上只有mul.w mulh.w mulh.wu这三条。
mul64x64模块试了下,下一个周期就能返回结果。
比如mul.w,试了下2 x 2和-1 x -1。
又试了下mulhwu,结果对,也是下个周期就返回。
其实就可以把这个结果按_m返回直接丢给rd_data_mux了。
网上搜了下,说mul指令是可以一个周期完成的,就是快就需要很多full adder,在以前的话比较费资源。
不过我还没时间好好学习这部分,直接用了chiplab里的mul64x64模块,连接口也没改。
1 module mul64x64(
2 input clk,
3 input rstn,
4
5 input mul_validin,
6 input ex2_allowin,
7 output mul_validout,
8 input ex1_readygo,
9 input ex2_readygo,
10
11 input [63:0] opa,
12 input [63:0] opb,
13 input mul_signed,
14 input mul64,
15 input mul_hi,
16 input mul_short,
17
18 output [63:0] mul_res_out,
19 output mul_ready
20 );
在调用的时候直接这样:
339 mul64x64 mul(
340 .clk (clk ),
341 .rstn (resetn ),
342
343 // .mul_validin (mul_valid ),
344 // .ex2_allowin (ex2_allow_in ),
345 // .mul_validout (ex2_mul_ready ),
346 // .ex1_readygo (ex1_allow_in ),
347 // .ex2_readygo (ex2_allow_in ),
348
349 .mul_validin (ecl_mul_valid_e ),
350 .ex2_allowin (1'b1 ),
351 .mul_validout (mul_ecl_64ready ),
352 .ex1_readygo (1'b1 ),
353 .ex2_readygo (1'b1 ),
354
355 .opa (mul_a_input ),
356 .opb (mul_b_input ),
357 .mul_signed (ecl_mul_signed_e ),
358 .mul64 (ecl_mul_double_e ),
359 .mul_hi (ecl_mul_hi_e ),
360 .mul_short (ecl_mul_short_e ),
361
362 .mul_res_out (mul_res_output ),
363 .mul_ready (mul_ecl_32ready )
364 );
不过这个接口给的方式可以是不固定周期的。
不知道现在这个mul64x64的模块如果连着执行两条mul指令会不会又影响。还没有仔细看代码,等后面又时间结合着opensparc的mul模块再好好学学。
我想试试exu_ifu_stall_req这个,和load指令一样把取值先停了,现在的情况是只用停一个cycle就好。
试了下连着执行两次mul,代码这样:
obj/main.elf: file format elf32-loongarch
obj/main.elf
Disassembly of section .text:
1c000000 <_start>:
kernel_entry():
1c000000: 02bffc03 addi.w $r3,$r0,-1(0xfff)
1c000004: 02815404 addi.w $r4,$r0,85(0x55)
1c000008: 02bd5806 addi.w $r6,$r0,-170(0xf56)
1c00000c: 029ea807 addi.w $r7,$r0,1962(0x7aa)
1c000010: 001d1065 mulh.wu $r5,$r3,$r4
1c000014: 001d1cc8 mulh.wu $r8,$r6,$r7
1c000018: 02800000 addi.w $r0,$r0,0
1c00001c: 02800000 addi.w $r0,$r0,0
1c000020: 02800000 addi.w $r0,$r0,0
1c000024: 02800000 addi.w $r0,$r0,0
1c000028: 02800000 addi.w $r0,$r0,0
1c00002c: 02800000 addi.w $r0,$r0,0
1c000030: 02800000 addi.w $r0,$r0,0
1c000034: 02800000 addi.w $r0,$r0,0
1c000038: 5bffc800 beq $r0,$r0,-56(0x3ffc8) # 1c000000 <_start>
这样看来还是在_m处理mul最方便。
如果多个cycle指令stall IFU的话,不光rd_data要mux,rd, wen都要mux。
mul先按_m返回结果处理吧,等以后div了再搞stall IFU。正好_m的时候可以mux。