📄 decode.v
字号:
// check register conflict
//------------------------
// following conditions mean register conflict
// (1) EX_RDREG_X and WB1_WRREG_W and (EX_REGNUM_X == WB1_REGNUM_W)
// (2) EX_RDREG_Y and WB1_WRREG_W and (EX_REGNUM_Y == WB1_REGNUM_W)
// (3) EX_WRREG_Z and WB1_WRREG_W and (EX_REGNUM_Z == WB1_REGNUM_W)
// (4) EX_RDPR_X and WB1_WRPR_W
// (5) EX_RDPR_Y and WB1_WRPR_W
// (6) EX_WRPR_Z and WB1_WRPR_W
// (7) (EX_ALUFUNC == `ALU_ADDR0) and WB1_WRREG_W and (WB1_REGNUM_W == 4'h0)
always @(EX_RDREG_X or EX_RDREG_Y or EX_WRREG_Z
or EX_REGNUM_X or EX_REGNUM_Y or EX_REGNUM_Z // Thorn Aitch 2003/12/10
or WB1_WRREG_W or WB1_REGNUM_W
or EX_RDPR_X or EX_RDPR_Y or EX_WRPR_Z
or WB1_WRPR_W
// or EX_RDMACH_X or EX_RDMACH_Y or WB1_WRMACH
// or EX_RDMACL_X or EX_RDMACL_Y or WB1_WRMACL
or EX_ALUFUNC)
//always @(posedge CLK)
begin
if ((EX_RDREG_X & WB1_WRREG_W & (EX_REGNUM_X == WB1_REGNUM_W))
| (EX_RDREG_Y & WB1_WRREG_W & (EX_REGNUM_Y == WB1_REGNUM_W))
| (EX_WRREG_Z & WB1_WRREG_W & (EX_REGNUM_Z == WB1_REGNUM_W))
| (EX_RDPR_X & WB1_WRPR_W)
| (EX_RDPR_Y & WB1_WRPR_W)
| (EX_WRPR_Z & WB1_WRPR_W)
// | (EX_RDMACH_X & WB1_WRMACH)
// | (EX_RDMACH_Y & WB1_WRMACH)
// | (EX_RDMACL_X & WB1_WRMACL)
// | (EX_RDMACL_Y & WB1_WRMACL)
| ((EX_ALUFUNC == `ALU_ADDR0) & WB1_WRREG_W & (WB1_REGNUM_W == 4'h0))
)
REG_CONF <= 1;
else
REG_CONF <= 0;
end
//---------------------------
// check forwarding condition
//---------------------------
// following conditions mean register forwarding from W-bus to X/Y-bus
// (1) RDREG_X and WRREG_W and (REGNUM_X == REGNUM_W) : W-bus to X-bus
// (2) RDREG_Y and WRREG_W and (REGNUM_Y == REGNUM_W) : W-bus to Y-bus
// (3) RDPR_X and WRPR_W : W-bus to X-bus
// (4) RDPR_Y and WRPR_W : W-bus to Y-bus
// (5) RDMACH_X and WRMACH : W-bus to X-bus
// (6) RDMACH_Y and WRMACH : W-bus to Y-bus
// (7) RDMACL_X and WRMACL : W-bus to X-bus
// (8) RDMACL_Y and WRMACL : W-bus to Y-bus
reg REG_FWD_X; // register forward from W-bus to X-bus
reg REG_FWD_Y; // register forward from W-bus to Y-bus
always @(RDREG_X or RDREG_Y
or REGNUM_X or REGNUM_Y
or WRREG_W or REGNUM_W
or RDPR_X or RDPR_Y or WRPR_W
// or RDMACH_X or RDMACH_Y or WRMACH
// or RDMACL_X or RDMACL_Y or WRMACL
or FWD_W2X)
begin
if ((FWD_W2X)
| (RDREG_X & WRREG_W & (REGNUM_X == REGNUM_W))
| (RDPR_X & WRPR_W))
// | (RDMACH_X & WRMACH)
// | (RDMACL_X & WRMACL)
REG_FWD_X <= 1'b1;
else
REG_FWD_X <= 1'b0;
if ((RDREG_Y & WRREG_W & (REGNUM_Y == REGNUM_W))
| (RDPR_Y & WRPR_W))
// | (RDMACH_Y & WRMACH)
// | (RDMACL_Y & WRMACL)
REG_FWD_Y <= 1'b1;
else
REG_FWD_Y <= 1'b0;
end
//------------------------------------
// Output Signals : A huge truth table
//------------------------------------
always @(INSTR_STATE or INSTR_SEQ or T_BCC or NEXT_ID_STALL)
begin
// ---- CAUTION ----------------------------------------------------------------
// To simplify the RTL description rule,
// only non-blocking substitution (<=) is recommended for this project.
// But in this "always @" statement,
// I use blocking substitution (=) to reduce typing errors.
// You should take care when you modify or reuse this statement.
//
// Moreover, in this scope area, I use casex to specify "don't care input ?".
// But the use of casex is permitted only for this truth table.
//------------------------------------------------------------------------------
//===============
// default values
//===============
DISPATCH = 0;
{ID_IF_ISSUE,ID_IF_JP} = 2'b00;
{EX_IF_ISSUE,EX_IF_JP} = 2'b00;
{EX_RDREG_X, EX_RDREG_Y, EX_WRREG_Z, WB_WRREG_W } = 4'b0000;
// {EX_REGNUM_X,EX_REGNUM_Y,EX_REGNUM_Z,WB_REGNUM_W} = 16'hxxxx; // Thorn Aitch 2003/12/10
{EX_REGNUM_X,EX_REGNUM_Y,EX_REGNUM_Z,WB_REGNUM_W} = 16'h0000; // Thorn Aitch 2003/12/10
{EX_ALUFUNC} = `ALU_NOP;
{EX_MULCOM1, EX_MULCOM2} = 9'b000000000;
{WB_MULCOM1, WB_MULCOM2} = 9'b000000000;
{EX_MACSEL1,EX_MACSEL2} = 4'b0000;
{WB_MACSEL1,WB_MACSEL2} = 4'b0000;
{EX_WRMACH,EX_WRMACL} = 2'b00;
{WB_WRMACH,WB_WRMACL} = 2'b00;
{EX_RDMACH_X,EX_RDMACL_X} = 2'b00;
{EX_RDMACH_Y,EX_RDMACL_Y} = 2'b00;
{WB_MAC_BUSY, EX_MAC_BUSY, MAC_STALL_SENSE} = 3'b000;
{EX_RDSR_X, EX_RDSR_Y, EX_WRSR_Z, WB_WRSR_W} = 4'b0000;
{MAC_S_LATCH} = 1'b0;
{EX_RDGBR_X, EX_RDGBR_Y, EX_WRGBR_Z, WB_WRGBR_W} = 4'b0000;
{EX_RDVBR_X, EX_RDVBR_Y, EX_WRVBR_Z, WB_WRVBR_W} = 4'b0000;
{EX_RDPR_X, EX_RDPR_Y, EX_WRPR_Z, WB_WRPR_W, EX_WRPR_PC} = 5'b00000;
// {EX_MA_ISSUE,EX_MA_WR,EX_MA_SZ,EX_KEEP_CYC} = 5'b0xxxx; // Thorn Aitch 2003/12/10
{EX_MA_ISSUE,EX_MA_WR,EX_MA_SZ,EX_KEEP_CYC} = 5'b00000; // Thorn Aitch 2003/12/10
{EX_WRMAAD_Z,EX_WRMADW_X,EX_WRMADW_Y,WB_RDMADR_W} = 4'b0000;
{EX_RDPC_X,EX_RDPC_Y,EX_WRPC_Z,ID_INCPC} = 4'b0000;
{ID_IFADSEL, EX_IFADSEL} = 2'b00;
{EX_CONST_ZERO4,EX_CONST_ZERO42,EX_CONST_ZERO44} = 3'b000;
{EX_CONST_ZERO8,EX_CONST_ZERO82,EX_CONST_ZERO84} = 3'b000;
{EX_CONST_SIGN8,EX_CONST_SIGN82,EX_CONST_SIGN122} = 3'b000;
{EX_RDCONST_X,EX_RDCONST_Y} = 2'b00;
// {EX_CMPCOM} = 3'bxxx; // Thorn Aitch 2003/12/10
{EX_CMPCOM} = 3'b000; // Thorn Aitch 2003/12/10
// {EX_SFTFUNC} = 5'bxxxx; // Thorn Aitch 2003/12/10
{EX_SFTFUNC} = 5'b0000; // Thorn Aitch 2003/12/10
{EX_RDSFT_Z} = 1'b0;
{EX_T_CMPSET, EX_T_CRYSET, EX_T_TSTSET, EX_T_SFTSET} = 4'b0000;
{EX_QT_DV1SET, EX_MQT_DV0SET} = 2'b00;
{EX_T_CLR, EX_T_SET, EX_MQ_CLR} = 3'b000;
{EX_RDTEMP_X, EX_WRTEMP_Z, EX_WRMAAD_TEMP} = 3'b000;
{EX_FWD_W2X} = 1'b0;
{EVENT_ACK_0, RST_SR, ILEVEL_CAP, WR_IBIT} = 4'b0000;
{MASKINT_NEXT} = 1'b0;
{SLP} = 1'b0;
{DELAY_JUMP} = 1'b0;
//============================================
// Line 0xxx
//============================================
casex (INSTR_STATE[15:12])
4'b0000 : // 0xxx
//------------------
// STC SR, Rn (0n02)
// STC GBR, Rn (0n12)
// STC VBR, Rn (0n22)
//------------------
casex (INSTR_STATE[3:0])
4'b0010 : // 0xx2
begin
casex (INSTR_STATE[5:4])
2'b00 : EX_RDSR_Y = 1'b1;
2'b01 : EX_RDGBR_Y = 1'b1;
2'b1? : EX_RDVBR_Y = 1'b1;
default : ;
endcase
EX_ALUFUNC = `ALU_THRUY;
EX_REGNUM_Z = INSTR_STATE[11:8]; // Rn
EX_WRREG_Z = 1'b1;
ID_INCPC = 1'b1;
ID_IF_ISSUE = 1'b1;
DISPATCH = 1'b1;
end
//---------------
// BSRF Rm (0m03)
// BRAF Rm (0m23)
//---------------
4'b0011 : // 0xx3
begin
case (INSTR_SEQ)
0: begin
EX_RDPC_X = 1'b1;
EX_RDREG_Y = 1'b1;
EX_REGNUM_Y = INSTR_STATE[11:8];
EX_ALUFUNC = `ALU_ADD;
EX_WRPC_Z = 1'b1;
if (~INSTR_STATE[5]) EX_WRPR_PC = 1; // BSRF operation
ID_INCPC = 1'b1;
end
1: begin
ID_IF_ISSUE = 1'b1;
ID_IFADSEL = 1'b1;
ID_IF_JP = 1'b1;
DISPATCH = 1'b1;
DELAY_JUMP = 1'b1;
end
default : ;
endcase
end
//---------------------------
// MUL.L Rm, Rn (0nm7)
//---------------------------
4'b01?? : // 0xx4, 0xx5, 0xx6, 0xx7
begin
if (INSTR_STATE[1:0] == 2'b11) // 0xx7
begin
MAC_STALL_SENSE = 1'b1;
EX_MAC_BUSY = (NEXT_ID_STALL)? 1'b0:1'b1;
EX_RDREG_X = 1'b1;
EX_REGNUM_X = INSTR_STATE[11:8]; // Rn
EX_RDREG_Y = 1'b1;
EX_REGNUM_Y = INSTR_STATE[7:4]; // Rm
EX_MACSEL1 = 2'b00; // XBUS -> MACIN1
EX_MACSEL2 = 2'b00; // YBUS -> MACIN2
EX_MULCOM1 = 1'b1;
EX_MULCOM2 = {1'b1, INSTR_STATE[14:12], INSTR_STATE[3:0]};
ID_INCPC = 1'b1;
ID_IF_ISSUE = 1'b1;
DISPATCH = 1'b1;
end
//---------------------------
// MOV.B Rm, @(R0, Rn) (0nm4)
// MOV.W Rm, @(R0, Rn) (0nm5)
// MOV.L Rm, @(R0, Rn) (0nm6)
//---------------------------
else // 0xx4, 0xx5, 0xx6
begin
EX_RDREG_X = 1'b1;
EX_REGNUM_X = INSTR_STATE[11:8]; //Rn
EX_ALUFUNC = `ALU_ADDR0; //@(R0, Rn)
EX_WRMAAD_Z = 1'b1;
EX_RDREG_Y = 1'b1;
EX_REGNUM_Y = INSTR_STATE[7:4]; //Rm
EX_WRMADW_Y = 1'b1;
{EX_MA_ISSUE,EX_MA_WR} = 2'b11;
EX_MA_SZ = INSTR_STATE[1:0];
ID_INCPC = 1'b1;
ID_IF_ISSUE = 1'b1;
DISPATCH = 1'b1;
end
end
//--------------
// CLRT (0008)
// SETT (0018)
// CLRMAC (0028)
//--------------
4'b1000 : // 0xx8
begin
casex (INSTR_STATE[5:4])
2'b00 : EX_T_CLR = 1'b1;
2'b01 : EX_T_SET = 1'b1;
2'b1? : {EX_WRMACH, EX_WRMACL, MAC_STALL_SENSE} = 3'b111;
default : ;
endcase
ID_INCPC = 1'b1;
ID_IF_ISSUE = 1'b1;
DISPATCH = 1'b1;
end
//---------------
// NOP (0009)
//---------------
4'b1001 : // 0xx9
begin
if(INSTR_STATE[5:4] == 2'b00) //(don't care INSTR_STATE[11:6])
begin // ID
ID_INCPC = 1'b1;
ID_IF_ISSUE = 1'b1;
DISPATCH = 1'b1;
end
//---------------
// DIV0U (0019)
//---------------
else if (INSTR_STATE[5:4] == 2'b01) //(don't care INSTR_STATE[11:6])
begin
EX_T_CLR = 1'b1;
EX_MQ_CLR = 1'b1;
ID_INCPC = 1'b1;
ID_IF_ISSUE = 1'b1;
DISPATCH = 1'b1;
end
//---------------
// MOVT Rn (0n29)
//---------------
else
begin
if (T_BCC) EX_ALUFUNC = `ALU_INCX; // if T=1 then 1->Rn else 0->Rn
EX_WRREG_Z = 1'b1;
EX_REGNUM_Z = INSTR_STATE[11:8];
ID_INCPC = 1'b1;
ID_IF_ISSUE = 1'b1;
DISPATCH = 1'b1;
end
end
//--------------------
// STS MACH, Rn (0n0A)
// STS MACL, Rn (0n1A)
// STS PR , Rn (0n2A)
//--------------------
4'b1010 : // 0xxA
begin
casex (INSTR_STATE[5:4])
2'b00 : // don't care INSTR_STATE[7:6]
{EX_RDMACH_Y, MAC_STALL_SENSE} = 2'b11;
2'b01 : // don't care INSTR_STATE[7:6]
{EX_RDMACL_Y, MAC_STALL_SENSE} = 2'b11;
2'b1? : EX_RDPR_Y = 1'b1; // don't care INSTR_STATE[7:6],[4]
default : ;
endcase
EX_ALUFUNC = `ALU_THRUY;
EX_REGNUM_Z = INSTR_STATE[11:8]; // Rn
EX_WRREG_Z = 1'b1;
ID_INCPC = 1'b1;
ID_IF_ISSUE = 1'b1;
DISPATCH = 1'b1;
end
//-----------
// RTS (000B)
//-----------
4'b1011 : // 0xxB
begin
if(INSTR_STATE[5:4] == 2'b00) // 000B (don't care INSTR_STATE[11:6])
case (INSTR_SEQ)
0: begin
EX_RDPR_Y = 1'b1;
EX_ALUFUNC = `ALU_THRUY;
EX_WRPC_Z = 1'b1;
end
1: begin
ID_IF_ISSUE = 1'b1;
ID_IFADSEL = 1'b1;
ID_IF_JP = 1'b1;
DISPATCH = 1'b1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -