2019.4.30添加
粗略通讀了整個蜂鳥e203的ALU子產品的代碼,其基本工作流程為:
在譯碼階段,已經讀取了對源操作數寄存器索引,源操作數的讀取,需要寫回的結果操作數,存在InfoBUS中的資訊等
下面是在e203_exu_decode.v檔案中對相關資訊的提取,順帶一提,在RISC-V架構中,x0寄存器是一個相對特殊的寄存器,在v2.2版本的使用者文檔中是這樣描述的:Register x0 is hardwired to the constant 0. 部落客英文水準與基礎的電路知識不佳,大緻意思是這個寄存器是通過硬體手段強行置0的,也就是說這個寄存器無法寫入值,其記憶體存放的永遠都是0;
//e203_exu_decode.v
module e203_exu_decode(
....
)
....
//以下為對指令譯碼得到的資訊
output dec_rs1x0,//源操作數1寄存器索引為x0
output dec_rs2x0,//源操作數2寄存器索引為x0
output dec_rs1en,//該指令需要讀取源操作數1
output dec_rs2en,//該指令需要讀取源操作數2
output dec_rdwen,//該指令需要寫回結果操作數
output ['E203_RGIDX_WIDTH-1:0] dec_rs1idx,//源操作數1寄存器索引
output ['E203_RGIDX_WIDTH-1:0] dec_rs2idx,//源操作數2寄存器索引
output ['E203_RGIDX_WIDTH-1:0] dec_rdidx,//結果操作數寄存器索引
output ['E203_DECINFO_WIDTH-1:0] dec_info,//其餘資訊統一存在INFOBUS中
output ['E203_XLEN-1:0] dec_imm,//該指令使用立即數
...
output dec_ilegl,//該指令非法
...
endmodule
通過上面的代碼片段可以看出譯碼完成後被傳入ALU中的信号已經很規整了,ALU當中的子子產品通過判斷info bus中的信号來确定接下來需要複用運算資料通路子子產品的具體部分,且可以認為此時兩個源操作數和需要用來存放結果的寄存器都已經取到了。再結合下面的部分看相信就對這部分的工作流程有個架構已經在大家的腦海中成型了。
**************************************分割線**************************************************
首次添加2019.3.28,計劃繼續補充修改
// This module to implement the regular ALU instructions
//
//
// ====================================================================
`include "e203_defines.v"
module e203_exu_alu_rglr(
//
//
// The Handshake Interface
//
input alu_i_valid, // Handshake valid寫入使能
output alu_i_ready, // Handshake ready寫入準備就緒
//E203_XLEN32bit
input [`E203_XLEN-1:0] alu_i_rs1,
input [`E203_XLEN-1:0] alu_i_rs2,
input [`E203_XLEN-1:0] alu_i_imm,
input [`E203_PC_SIZE-1:0] alu_i_pc,
//目前E203_DECINFO_ALU_WIDTH為21[20:0],此項為從info總線取到的資料
input [`E203_DECINFO_ALU_WIDTH-1:0] alu_i_info,
//
//
// The ALU Write-back/Commit Interface
output alu_o_valid, // Handshake valid輸出使能
input alu_o_ready, // Handshake ready輸出就緒或完成
// The Write-Back Interface for Special (unaligned ldst and AMO instructions)
output [`E203_XLEN-1:0] alu_o_wbck_wdat,//連接配接至資料通路傳回的結果,即寫回的資料
output alu_o_wbck_err,
output alu_o_cmt_ecall,
output alu_o_cmt_ebreak,
output alu_o_cmt_wfi,
//
//
// To share the ALU datapath将發送至資料通路的資料
//
// The operands and info to ALU
output alu_req_alu_add ,
output alu_req_alu_sub ,
output alu_req_alu_xor ,
output alu_req_alu_sll ,
output alu_req_alu_srl ,
output alu_req_alu_sra ,
output alu_req_alu_or ,
output alu_req_alu_and ,
output alu_req_alu_slt ,
output alu_req_alu_sltu,
output alu_req_alu_lui ,
output [`E203_XLEN-1:0] alu_req_alu_op1,//兩個源操作數
output [`E203_XLEN-1:0] alu_req_alu_op2,
input [`E203_XLEN-1:0] alu_req_alu_res,//從資料通路子產品取回的結果
input clk,
input rst_n
);
wire op1pc = alu_i_info [`E203_DECINFO_ALU_OP1PC ];//判定第一個源操作數是否使用PC 16:16
wire op2imm = alu_i_info [`E203_DECINFO_ALU_OP2IMM ];//判定第二個源操作數是否為立即數 15:15
assign alu_req_alu_op1 = op1pc ? alu_i_pc : alu_i_rs1;//兩個源操作數
assign alu_req_alu_op2 = op2imm ? alu_i_imm : alu_i_rs2;
wire nop = alu_i_info [`E203_DECINFO_ALU_NOP ] ;//17:17
wire ecall = alu_i_info [`E203_DECINFO_ALU_ECAL ];//18:18
wire ebreak = alu_i_info [`E203_DECINFO_ALU_EBRK ];//19:19
wire wfi = alu_i_info [`E203_DECINFO_ALU_WFI ];//20:20
// The NOP is encoded as ADDI, so need to uncheck it
assign alu_req_alu_add = alu_i_info [`E203_DECINFO_ALU_ADD ] & (~nop);//4:4
assign alu_req_alu_sub = alu_i_info [`E203_DECINFO_ALU_SUB ];//5:5
assign alu_req_alu_xor = alu_i_info [`E203_DECINFO_ALU_XOR ];//6:6
assign alu_req_alu_sll = alu_i_info [`E203_DECINFO_ALU_SLL ];//7
assign alu_req_alu_srl = alu_i_info [`E203_DECINFO_ALU_SRL ];//8
assign alu_req_alu_sra = alu_i_info [`E203_DECINFO_ALU_SRA ];//9
assign alu_req_alu_or = alu_i_info [`E203_DECINFO_ALU_OR ];//10
assign alu_req_alu_and = alu_i_info [`E203_DECINFO_ALU_AND ];//11
assign alu_req_alu_slt = alu_i_info [`E203_DECINFO_ALU_SLT ];//12
assign alu_req_alu_sltu = alu_i_info [`E203_DECINFO_ALU_SLTU];//13
assign alu_req_alu_lui = alu_i_info [`E203_DECINFO_ALU_LUI ];//14:14
assign alu_o_valid = alu_i_valid;//根據輸入使能得到輸出使能
assign alu_i_ready = alu_o_ready;//
assign alu_o_wbck_wdat = alu_req_alu_res;//将從資料通路取回的資料輸出
assign alu_o_cmt_ecall = ecall;
assign alu_o_cmt_ebreak = ebreak;
assign alu_o_cmt_wfi = wfi;
// The exception or error result cannot write-back
assign alu_o_wbck_err = alu_o_cmt_ecall | alu_o_cmt_ebreak | alu_o_cmt_wfi;
endmodule