|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
`define SIM
`define LOW_POWER
`timescale 1ns/100ps
`include "../RTL/instruction_opcode.v"
module Kunlun_r_5c_bus
#(
//Upon reset, this reset address is loaded into PC
parameter RESET_ADDRESS=32'H0
)
(
// clock and reset
input clk,
input rst_n,
// I master interface
output logic i_read,
input logic i_waitrequest,
output logic [31: 0] i_address,
input logic [31: 0] i_readdata,
// D master interface
output logic d_read,
output logic d_write,
input logic d_waitrequest,
output logic [31: 0] d_address,
input logic [31: 0] d_readdata,
output logic [31: 0] d_writedata,
output logic [ 3: 0] d_byteenable
);
parameter DLY = 1;
//////////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////////
logic [31: 0] PC;
logic [31: 0] IR;
logic IR_wr;
logic [31: 0] RFile[0:31];
logic [31: 0] rA,rB,rIMM;
logic [31: 0] rALU;
wire [ 5: 0] IR_op = IR[ 5: 0];
wire [ 4: 0] IR_a = IR[31:27];
wire [ 4: 0] IR_b = IR[26:22];
wire [ 4: 0] IR_c = IR[21:17];
wire [ 5: 0] IR_opx = IR[16:11];
wire [ 5: 0] IR_imm5 = IR[10: 6];
wire [15: 0] IR_imm16 = IR[21: 6];
wire [25: 0] IR_imm26 = IR[31: 6];
logic [31: 0] IR_d;
parameter ZERO_IDX = 5'h00;
parameter RA_IDX = 5'h1F;
//flag for R-Type instructions
wire IR_IsRType = (IR_op==6'h3A);
//flag for J-Type instructions
wire IR_IsJType = ( (IR_op==`IR_J_CALL) ||
(IR_op==`IR_J_JMPI)
) ;
//flag for I-Type instructions
wire IR_IsIType = !(IR_IsRType||IR_IsJType);
//flag for LDx instructions
wire IR_IsLD = ( IR_op==`IR_I_LDB || IR_op==`IR_I_LDBU ||
IR_op==`IR_I_LDBIO|| IR_op==`IR_I_LDBUIO ||
IR_op==`IR_I_LDH || IR_op==`IR_I_LDHU ||
IR_op==`IR_I_LDHIO|| IR_op==`IR_I_LDHUIO ||
IR_op==`IR_I_LDW || IR_op==`IR_I_LDWIO
);
//flag for STx instructions
wire IR_IsST = ( IR_op==`IR_I_STB || IR_op==`IR_I_STBIO ||
IR_op==`IR_I_STH || IR_op==`IR_I_STHIO ||
IR_op==`IR_I_STW || IR_op==`IR_I_STWIO
);
//flag for BRx instructions
wire IR_IsBR = ( IR_op==`IR_I_BR || IR_op==`IR_I_BGE ||
IR_op==`IR_I_BLT || IR_op==`IR_I_BNE ||
IR_op==`IR_I_BEQ || IR_op==`IR_I_BGEU ||
IR_op==`IR_I_BLTU
);
////////////////////////////////////////////////////////////////////////////////
// 1: PC
////////////////////////////////////////////////////////////////////////////////
logic [31: 0] PC_d;
logic PC_wr;
enum logic [ 3: 0] { PC_d_sel_PCP4 = 4'b0001,
PC_d_sel_BR = 4'b0010,
PC_d_sel_JMP = 4'b0100,
PC_d_sel_RA = 4'b1000,
PC_d_sel_X = 4'bxxxx
} PC_d_sel;
always_ff @( posedge clk, negedge rst_n )
begin
if ( ~rst_n ) PC <= RESET_ADDRESS;
else if ( PC_wr ) PC <= #DLY PC_d;
//else PC <= #DLY PC;
end
always_comb
begin
unique case( PC_d_sel )
PC_d_sel_PCP4 : PC_d = PC + 32'd4;
PC_d_sel_BR : PC_d = PC + {{16{IR_imm16[15]}},IR_imm16};
PC_d_sel_JMP : PC_d = {PC[31:28], IR_imm26, 2'b00};
PC_d_sel_RA : PC_d = rA;
default : PC_d = 'x;
endcase
end
/////////////////////////////////////////////////////////////////////////////
// 2: I Master Interface
/////////////////////////////////////////////////////////////////////////////
logic is_in_stageF;
logic i_fetch_done;
always_comb
assign i_address = PC;
assign IR_d = i_readdata;
always_comb
begin: i_read_of_StageF
if ( is_in_stageF==1'b1 )
i_read = 1'b1;
else
i_read = 1'b0;
end: i_read_of_StageF
always_comb
begin: i_fetch_done_of_StageF
if ( (is_in_stageF==1'b1) && (i_waitrequest==1'b0) )
i_fetch_done = 1'b1;
else
i_fetch_done = 1'b0;
end: i_fetch_done_of_StageF
always_comb
begin: IR_wr_of_StageF
if ( (is_in_stageF==1'b1) && (i_waitrequest==1'b0) )
IR_wr = 1'b1;
else
IR_wr = 1'b0;
end: IR_wr_of_StageF
///////////////////////////////////////////////////////////////////////////////
// 3: IR
///////////////////////////////////////////////////////////////////////////////
always_ff @(posedge clk, negedge rst_n)
begin
if ( ~rst_n ) IR <= 32'd0;
else if ( IR_wr ) IR <= #DLY i_readdata;
end
///////////////////////////////////////////////////////////////////////////////
// 4: rA, rB, rIMM
///////////////////////////////////////////////////////////////////////////////
logic [ 4: 0] RFile_Aidx,RFile_Bidx;
logic [31: 0] RFile_Aq,RFile_Bq;
logic [31: 0] rIMM_d;
logic rIMM_wr;
enum logic [ 3: 0] { rIMM_d_sel_IR_IMM16_SE = 4'b0001,
rIMM_d_sel_IR_IMM16_ZE = 4'b0010,
rIMM_d_sel_IR_IMM16_LS16 = 4'b0100,
rIMM_d_sel_IR_IMM5_ZE = 4'b1000,
rIMM_d_sel_X = 4'bxxxx
} rIMM_d_sel;
assign RFile_Aidx = IR_a;
assign RFile_Bidx = IR_b;
assign RFile_Aq = (RFile_Aidx==ZERO_IDX) ? 32'd0 : RFile[RFile_Aidx];
assign RFile_Bq = (RFile_Bidx==ZERO_IDX) ? 32'd0 : RFile[RFile_Bidx];
always_ff @(posedge clk,negedge rst_n)
begin: update_rA
if ( rst_n==1'b0 )
rA <= 32'd0;
else
rA <= #DLY RFile_Aq;
end: update_rA
always_ff @(posedge clk,negedge rst_n)
begin: update_rB
if ( rst_n==1'b0 )
rB <= 32'd0;
else
rB <= #DLY RFile_Bq;
end: update_rB
always_ff @(posedge clk,negedge rst_n)
begin: update_rIMM
if ( rst_n==1'b0 )
rIMM <= 32'd0;
else if ( rIMM_wr==1'b1 )
rIMM <= #DLY rIMM_d;
end: update_rIMM
always_comb
begin
unique case ( rIMM_d_sel )
rIMM_d_sel_IR_IMM16_SE : rIMM_d = { {16{IR_imm16[15]}}, IR_imm16 };
rIMM_d_sel_IR_IMM16_ZE : rIMM_d = { 16'd0, IR_imm16 };
rIMM_d_sel_IR_IMM16_LS16: rIMM_d = { IR_imm16, 16'd0 };
rIMM_d_sel_IR_IMM5_ZE : rIMM_d = { 27'd0, IR_imm5 };
default : rIMM_d = 'x;
endcase
end
///////////////////////////////////////////////////////////////////////////////
// 5: ALU
///////////////////////////////////////////////////////////////////////////////
logic [31: 0] ALU_a,ALU_b, ALU_q;
enum logic [ 1: 0] { ALU_b_sel_rB = 2'b01,
ALU_b_sel_rIMM = 2'b10,
ALU_b_sel_X = 2'bxx
} ALU_b_sel;
enum logic [23: 0] {
ALU_OP_ADD =24'h0_0_0_0_0_1,
ALU_OP_AND =24'h0_0_0_0_0_2,
ALU_OP_CMPEQ =24'h0_0_0_0_0_4,
ALU_OP_CMPGE =24'h0_0_0_0_0_8,
ALU_OP_CMPGEU =24'h0_0_0_0_1_0,
ALU_OP_CMPLT =24'h0_0_0_0_2_0,
ALU_OP_CMPLTU =24'h0_0_0_0_4_0,
ALU_OP_CMPNEQ =24'h0_0_0_0_8_0,
ALU_OP_MUL =24'h0_0_0_1_0_0,
ALU_OP_NOR =24'h0_0_0_2_0_0,
ALU_OP_OR =24'h0_0_0_4_0_0,
ALU_OP_ROL =24'h0_0_0_8_0_0,
ALU_OP_ROR =24'h0_0_1_0_0_0,
ALU_OP_SLL =24'h0_0_2_0_0_0,
ALU_OP_SRL =24'h0_0_4_0_0_0,
ALU_OP_SRA =24'h0_0_8_0_0_0,
ALU_OP_SUB =24'h0_1_0_0_0_0,
ALU_OP_XOR =24'h0_2_0_0_0_0,
ALU_OP_X =24'hx_x_x_x_x_x
} ALU_op;
logic rALU_wr;
assign ALU_a = rA;
always_comb
begin: ALU_b_selection
unique case ( ALU_b_sel )
ALU_b_sel_rB : ALU_b = rB;
ALU_b_sel_rIMM : ALU_b = rIMM;
default : ALU_b = 'x;
endcase
end: ALU_b_selection
always_comb
begin: ALU_computation
case ( ALU_op )
ALU_OP_ADD : ALU_q = ALU_a + ALU_b;
ALU_OP_AND : ALU_q = ALU_a & ALU_b;
ALU_OP_CMPEQ : ALU_q = ALU_a == ALU_b;
ALU_OP_CMPGE : ALU_q = cmpge( ALU_a, ALU_b );
ALU_OP_CMPGEU : ALU_q = ALU_a >= ALU_b;
ALU_OP_CMPLT : ALU_q = cmplt( ALU_a, ALU_b );
ALU_OP_CMPLTU : ALU_q = ALU_a < ALU_b;
ALU_OP_CMPNEQ : ALU_q = ALU_a != ALU_b;
ALU_OP_MUL : ALU_q = ALU_a * ALU_b;
ALU_OP_NOR : ALU_q = ~(ALU_a | ALU_b);
ALU_OP_OR : ALU_q = ALU_a | ALU_b ;
ALU_OP_ROL : ALU_q = rol( ALU_a, ALU_b[4:0] );
ALU_OP_ROR : ALU_q = ror( ALU_a, ALU_b[4:0] );
ALU_OP_SLL : ALU_q = ALU_a << ALU_b[4:0] ;
ALU_OP_SRL : ALU_q = ALU_a >> ALU_b[4:0] ;
ALU_OP_SRA : ALU_q = $signed(ALU_a) >>> ALU_b[4:0] ;
ALU_OP_SUB : ALU_q = ALU_a - ALU_b ;
ALU_OP_XOR : ALU_q = ALU_a ^ ALU_b ;
default : ALU_q = 'x;
endcase
end: ALU_computation
always_ff @(posedge clk)
begin: update_rALU
if ( rALU_wr==1'b1 )
rALU <= #DLY ALU_q;
end: update_rALU
////////////////////////////////////////////////////////////////////////////////
// 6: D Master Infterface //
////////////////////////////////////////////////////////////////////////////////
logic is_in_stageMEM;
logic [31: 0] data_from_DMaster;
logic [31: 0] rDMasterIn;
logic rDMasterIn_wr;
logic [ 7: 0] d_readdata_b;
logic [15: 0] d_readdata_h;
// the address of data bus comes always from rALU, ie. rA + sign(IMM16)
assign d_address = rALU;
//-----------store data into memory------------//
//------ d_writedata ------//
always_comb
begin: d_writedata_for_STX
unique if ( (IR_op==`IR_I_STB)|| (IR_op==`IR_I_STBIO) )
begin: d_writedata_for_STBx
d_writedata = { 4{rB[ 7: 0]} };
end: d_writedata_for_STBx
else if ( (IR_op==`IR_I_STH)|| (IR_op==`IR_I_STHIO) )
begin: d_writedata_for_STHx
d_writedata = { 2{rB[15: 0]} };
end: d_writedata_for_STHx
else
begin: d_writedata_for_STWx
d_writedata = rB;
end: d_writedata_for_STWx
end: d_writedata_for_STX
//------ d_write ------//
always_comb
begin: d_write_for_STX
if ( is_in_stageMEM && IR_IsST )
d_write = 1'b1;
else
d_write = 1'b0;
end: d_write_for_STX
//-------data_from_DMaster-------//
always_comb
begin: d_readdata_b_selection
if ( IR_op==`IR_I_LDB || IR_op==`IR_I_LDBU ||
IR_op==`IR_I_LDBIO|| IR_op==`IR_I_LDBUIO )
begin
unique case( d_address[ 1: 0] )
2'b00 : d_readdata_b = d_readdata[ 7: 0];
2'b01 : d_readdata_b = d_readdata[15: 8];
2'b10 : d_readdata_b = d_readdata[23:16];
2'b11 : d_readdata_b = d_readdata[31:24];
default : d_readdata_b = 'x;
endcase
end
else
d_readdata_b = 'x;
end: d_readdata_b_selection
always_comb
begin: d_readdata_h_selection
if ( IR_op==`IR_I_LDH || IR_op==`IR_I_LDHU ||
IR_op==`IR_I_LDHIO|| IR_op==`IR_I_LDHUIO )
begin
unique case( d_address[ 0] )
1'b0 : d_readdata_h = d_readdata[15: 0];
1'b1 : d_readdata_h = d_readdata[31:16];
default : d_readdata_h = 'x;
endcase
end
else
d_readdata_h = 'x;
end: d_readdata_h_selection
always_comb
begin: data_from_DMaster_selection
unique if ( IR_op==`IR_I_LDB|| IR_op==`IR_I_LDBIO )
data_from_DMaster = { {24{d_readdata_b[ 7]}}, d_readdata_b };
else if ( IR_op==`IR_I_LDBU|| IR_op==`IR_I_LDBUIO )
data_from_DMaster = { 24'd0, d_readdata_b };
else if ( IR_op==`IR_I_LDH|| IR_op==`IR_I_LDHIO )
data_from_DMaster = { {16{d_readdata_h[15]}}, d_readdata_h };
else if ( IR_op==`IR_I_LDHU|| IR_op==`IR_I_LDHUIO )
data_from_DMaster = { 16'd0, d_readdata_h };
else
data_from_DMaster = d_readdata;
end: data_from_DMaster_selection
//-------RDMasterIn_wr-------//
always_comb
begin
if ( is_in_stageMEM && !d_waitrequest && IR_IsLD )
rDMasterIn_wr = 1'b1;
else
rDMasterIn_wr = 1'b0;
end
//-------rDMasterIn------//
always_ff @( posedge clk, negedge rst_n )
begin
if ( ~rst_n )
rDMasterIn <= 32'd0;
else if ( rDMasterIn_wr )
rDMasterIn <= data_from_DMaster;
end
//------ d_read------//
always_comb
begin: d_read_for_LDX
if ( is_in_stageMEM && IR_IsLD )
d_read = 1'b1;
else
d_read = 1'b0;
end: d_read_for_LDX
//--------d_byteenable-------//
always_comb
begin
unique if ( IR_op==`IR_I_LDB || IR_op==`IR_I_LDBU ||
IR_op==`IR_I_LDBIO|| IR_op==`IR_I_LDBUIO||
IR_op==`IR_I_STB || IR_op==`IR_I_STBIO )
begin
unique case ( d_address[ 1: 0] )
2'b00 : d_byteenable = 4'b0001;
2'b01 : d_byteenable = 4'b0010;
2'b10 : d_byteenable = 4'b0100;
2'b11 : d_byteenable = 4'b1000;
default : d_byteenable = 'x;
endcase
end
else if ( IR_op==`IR_I_LDH || IR_op==`IR_I_LDHU ||
IR_op==`IR_I_LDHIO|| IR_op==`IR_I_LDHUIO||
IR_op==`IR_I_STH || IR_op==`IR_I_STHIO )
begin
unique case ( d_address[ 0] )
1'b0 : d_byteenable = 4'b0011;
1'b1 : d_byteenable = 4'b1100;
default : d_byteenable = 'x;
endcase
end
else
d_byteenable = 4'b1111;
end
///////////////////////////////////////////////////////////////////////////////
// 7: write_back RFile
///////////////////////////////////////////////////////////////////////////////
enum logic [ 2: 0] { RFile_Cidx_sel_IR_B = 3'b001,
RFile_Cidx_sel_IR_C = 3'b010,
RFile_Cidx_sel_RA = 3'b100,
RFile_Cidx_sel_X = 3'bxxx
} RFile_Cidx_sel;
enum logic [ 2: 0] { RFile_Cd_sel_rALU = 3'b001,
RFile_Cd_sel_DMaster = 3'b010,
RFile_Cd_sel_PC = 3'b100,
RFile_Cd_sel_X = 3'bxxx
} RFile_Cd_sel;
logic [ 4: 0] RFile_Cidx;
logic [31: 0] RFile_Cd;
logic RFile_Cwr;
//------ RFile_Cidx ------//
always_comb
begin : RFile_Cidx_Multiplexer
unique case( RFile_Cidx_sel )
RFile_Cidx_sel_IR_B: RFile_Cidx = IR_b;
RFile_Cidx_sel_IR_C: RFile_Cidx = IR_c;
RFile_Cidx_sel_RA : RFile_Cidx = RA_IDX;
default : RFile_Cidx = 'x;
endcase
end
//------ RFile_Cd ------//
always_comb
begin : RFile_Cd_Multiplexer
unique case( RFile_Cd_sel )
RFile_Cd_sel_rALU : RFile_Cd = rALU;
RFile_Cd_sel_DMaster : RFile_Cd = rDMasterIn;
RFile_Cd_sel_PC : RFile_Cd = PC;
default : RFile_Cd = 'x;
endcase
end
//------ write RFile ------//
always_ff @(posedge clk)
begin
if ( RFile_Cwr )
RFile[ RFile_Cidx ] <= #DLY RFile_Cd;
end
////////////////////////////////////////////////////////////////////////////////
// 0_A: Main Controller //
////////////////////////////////////////////////////////////////////////////////
enum logic [ 5: 0] { S_IDLE=6'd1, S_FETCH=6'd2, S_DECODE=6'd4,
S_EXE =6'd8, S_MEM =6'd16,S_WB =6'd32
} cur_stage, next_stage;
// update current stage
always_ff @(posedge clk, negedge rst_n)
begin
if ( ~rst_n ) cur_stage <= S_IDLE;
else cur_stage <= #DLY next_stage;
end
// next stage
always_comb
begin
unique case( cur_stage )
S_IDLE : next_stage = S_FETCH;
S_FETCH : begin
if( i_waitrequest==1'b0 )
next_stage = S_DECODE;
else
next_stage = S_FETCH;
end
S_DECODE: next_stage = S_EXE;
S_EXE : next_stage = S_MEM;
S_MEM : begin
if( d_waitrequest==1'b0 )
next_stage = S_WB;
else
next_stage = S_MEM;
end
S_WB : next_stage = S_FETCH;
default : next_stage = S_IDLE;
endcase
end
//
assign is_in_stageF = (cur_stage==S_FETCH);
assign is_in_stageMEM = (cur_stage==S_MEM);
////////////////////////////////////////////////////////////////////////////////
// 0_B: Control Signals //
////////////////////////////////////////////////////////////////////////////////
// Control signals: PC_wr, PC_d_sel,
// rIMM_d_sel
// ALU_b_sel, ALU_op, rALU_wr
// RFile_Cwr, RFile_Cidx_sel,RFile_Cd_sel
always_comb
begin: control_signal_gen
unique if ( cur_stage == S_FETCH )
begin: decoding_for_StageF
// PC
PC_wr = ~i_waitrequest;
PC_d_sel = PC_d_sel_PCP4;
// rIMM
rIMM_wr = 1'b0;
rIMM_d_sel = rIMM_d_sel_X;
// ALU
ALU_b_sel = ALU_b_sel_X;
ALU_op = ALU_OP_X;
rALU_wr = 1'b0;
// Write back RFile
RFile_Cwr = 1'b0;
RFile_Cidx_sel = RFile_Cidx_sel_X;
RFile_Cd_sel = RFile_Cd_sel_X;
end: decoding_for_StageF
else if ( cur_stage == S_DECODE )
begin: Decoding_for_StageD
// PC
PC_wr = 1'b0;
PC_d_sel = PC_d_sel_X;
// rIMM
rIMM_wr = 1'b1;
unique if (
IR_op==`IR_I_ADDI ||
IR_op==`IR_I_CMPEQI || IR_op==`IR_I_CMPGEI ||
IR_op==`IR_I_CMPLTI || IR_op==`IR_I_CMPNEI ||
IR_op==`IR_I_LDB || IR_op==`IR_I_LDH ||
IR_op==`IR_I_LDW ||
IR_op==`IR_I_LDBU || IR_op==`IR_I_LDHU ||
IR_op==`IR_I_MULI ||
IR_op==`IR_I_STB || IR_op==`IR_I_STH ||
IR_op==`IR_I_STW
)
rIMM_d_sel = rIMM_d_sel_IR_IMM16_SE;
else if (
IR_op==`IR_I_ANDI ||
IR_op==`IR_I_CMPGEUI || IR_op==`IR_I_CMPLTUI ||
IR_op==`IR_I_ORI || IR_op==`IR_I_XORI
)
rIMM_d_sel = rIMM_d_sel_IR_IMM16_ZE;
else if (
IR_op==`IR_I_ANDHI || IR_op==`IR_I_ORHI ||
IR_op==`IR_I_XORHI
)
rIMM_d_sel = rIMM_d_sel_IR_IMM16_LS16;
else if ( (IR_IsRType==1'b1) &&
( IR_opx==`IR_R_ROLI || IR_opx==`IR_R_SLLI ||
IR_opx==`IR_R_SRAI || IR_opx==`IR_R_SRLI )
)
rIMM_d_sel = rIMM_d_sel_IR_IMM5_ZE;
else
rIMM_d_sel = rIMM_d_sel_X;
// ALU
rALU_wr = 1'b0;
ALU_b_sel = ALU_b_sel_X;
ALU_op = ALU_OP_X;
// Write back RFile
RFile_Cwr = 1'b0;
RFile_Cidx_sel = RFile_Cidx_sel_X;
RFile_Cd_sel = RFile_Cd_sel_X;
endecoding_for_StageD
else if ( cur_stage == S_EXE )
begin: decoding_for_StageExe
// PC
PC_wr = 1'b0;
PC_d_sel = PC_d_sel_X;
// rIMM
rIMM_wr = 1'b0;
rIMM_d_sel = rIMM_d_sel_X;
// ALU
rALU_wr = 1'b1;
if ( ( (IR_IsRType==1'b1) &&
(IR_opx!=`IR_R_ROLI) &&
(IR_opx!=`IR_R_SLLI) &&
(IR_opx!=`IR_R_SRAI) &&
(IR_opx!=`IR_R_SRLI)
) || IR_IsBR
)
ALU_b_sel = ALU_b_sel_rB;
else
ALU_b_sel = ALU_b_sel_rIMM;
unique if( (IR_IsRType && (IR_opx==`IR_R_ADD ) ) ||
(IR_op ==`IR_I_ADDI) ||
(IR_op ==`IR_I_LDB ) ||
(IR_op ==`IR_I_LDBU) ||
(IR_op ==`IR_I_LDH ) ||
(IR_op ==`IR_I_LDHU) ||
(IR_op ==`IR_I_LDW ) ||
(IR_op ==`IR_I_STB ) ||
(IR_op ==`IR_I_STH ) ||
(IR_op ==`IR_I_STW )
)
ALU_op = ALU_OP_ADD;
// and
else if(
(IR_IsRType && (IR_opx==`IR_R_AND ) ) ||
(IR_op ==`IR_I_ANDHI) ||
(IR_op ==`IR_I_ANDI )
)
ALU_op = ALU_OP_AND;
// CMPEQ
else if(
(IR_IsRType && (IR_opx==`IR_R_CMPEQ ) ) ||
(IR_op ==`IR_I_BEQ ) ||
(IR_op ==`IR_I_CMPEQI)
)
ALU_op = ALU_OP_CMPEQ;
// CMPGE
else if(
(IR_IsRType && (IR_opx==`IR_R_CMPGE ) ) ||
(IR_op ==`IR_I_BGE ) ||
(IR_op ==`IR_I_CMPGEI )
)
ALU_op = ALU_OP_CMPGE;
// CMPGEU
else if(
(IR_op ==`IR_I_BGEU ) ||
(IR_IsRType && (IR_opx==`IR_R_CMPGEU) ) ||
(IR_op ==`IR_I_CMPGEUI )
)
ALU_op = ALU_OP_CMPGEU;
// CMPLT
else if(
(IR_op ==`IR_I_BLT ) ||
(IR_IsRType && (IR_opx==`IR_R_CMPLT) ) ||
(IR_op ==`IR_I_CMPLTI )
)
ALU_op = ALU_OP_CMPLT;
// CMPLTU
else if(
(IR_op ==`IR_I_BLTU ) ||
(IR_IsRType && (IR_opx==`IR_R_CMPLTU) ) ||
(IR_op ==`IR_I_CMPLTUI )
)
ALU_op = ALU_OP_CMPLTU;
// CMPNE
else if(
(IR_op ==`IR_I_BNE ) ||
(IR_IsRType && (IR_opx==`IR_R_CMPNE) ) ||
(IR_op ==`IR_I_CMPNEI )
)
ALU_op = ALU_OP_CMPNEQ;
// MUL
else if(
(IR_IsRType && (IR_opx==`IR_R_MUL) ) ||
(IR_op ==`IR_I_MULI )
)
ALU_op = ALU_OP_MUL;
// NOR
else if(
(IR_IsRType && (IR_opx==`IR_R_NOR) )
)
ALU_op = ALU_OP_NOR;
// OR
else if(
(IR_IsRType && (IR_opx==`IR_R_OR) ) ||
(IR_op ==`IR_I_ORHI ) ||
(IR_op ==`IR_I_ORI )
)
ALU_op = ALU_OP_OR;
// ROL
else if(
IR_IsRType && ( (IR_opx==`IR_R_ROL ) ||
(IR_opx==`IR_R_ROLI )
)
)
ALU_op = ALU_OP_ROL;
// ROR
else if(
(IR_IsRType && (IR_opx==`IR_R_ROR) )
)
ALU_op = ALU_OP_ROR;
// SLL
else if(
(IR_IsRType && (IR_opx==`IR_R_SLL ) ) ||
(IR_IsRType && (IR_opx==`IR_R_SLLI) )
)
ALU_op = ALU_OP_SLL;
// SRA
else if(
(IR_IsRType && (IR_opx==`IR_R_SRA ) ) ||
(IR_IsRType && (IR_opx==`IR_R_SRAI) )
)
ALU_op = ALU_OP_SRA;
// SRL
else if(
(IR_IsRType && (IR_opx==`IR_R_SRL ) ) ||
(IR_IsRType && (IR_opx==`IR_R_SRLI) )
)
ALU_op = ALU_OP_SRL;
// SUB
else if( IR_IsRType && (IR_opx==`IR_R_SUB ) )
ALU_op = ALU_OP_SUB;
// XOR
else if( (IR_IsRType && (IR_opx==`IR_R_XOR ) ) ||
(IR_op ==`IR_I_XORHI ) ||
(IR_op ==`IR_I_XORI )
)
ALU_op = ALU_OP_XOR;
//
else
ALU_op = ALU_OP_ADD;
// Write back RFile
RFile_Cwr = 1'b0;
RFile_Cidx_sel = RFile_Cidx_sel_X;
RFile_Cd_sel = RFile_Cd_sel_X;
end: decoding_for_StageExe
else if ( cur_stage == S_MEM )
begin: decoding_for_StageMem
// PC
PC_wr = 1'b0;
PC_d_sel = PC_d_sel_X;
// rIMM
rIMM_wr = 1'b0;
rIMM_d_sel = rIMM_d_sel_X;
// ALU
ALU_b_sel = ALU_b_sel_X;
ALU_op = ALU_OP_X;
rALU_wr = 1'b0;
// Write back RFile
RFile_Cwr = 1'b0;
RFile_Cidx_sel = RFile_Cidx_sel_X;
RFile_Cd_sel = RFile_Cd_sel_X;
end: decoding_for_StageMem
else if ( cur_stage == S_WB )
begin: decoding_for_StageWB
//------ PC ------//
unique if ( (IR_op==`IR_I_BEQ) || (IR_op==`IR_I_BGE) || (IR_op==`IR_I_BGEU)||
(IR_op==`IR_I_BLT) || (IR_op==`IR_I_BLTU)|| (IR_op==`IR_I_BNE )
)
PC_wr = (rALU[0]==1'b1) ? 1'b1 : 1'b0;
else if ( (IR_op==`IR_I_BR ) || (IR_op==`IR_J_CALL) || (IR_op==`IR_J_JMPI) ||
( (IR_IsRType==1'b1)&&( (IR_opx==`IR_R_CALLR)||(IR_opx==`IR_R_JMP)||
(IR_opx==`IR_R_RET) ) )
)
PC_wr = 1'b1;
else
PC_wr = 1'b0;
unique if( (IR_op==`IR_I_BEQ )|| (IR_op==`IR_I_BGE )|| (IR_op==`IR_I_BGEU) ||
(IR_op==`IR_I_BLT )|| (IR_op==`IR_I_BLTU)|| (IR_op==`IR_I_BNE ) ||
(IR_op==`IR_I_BR ) )
PC_d_sel = PC_d_sel_BR;
else if( IR_IsJType==1'b1 )
PC_d_sel = PC_d_sel_JMP;
else if( (IR_IsRType==1'b1 ) && ( (IR_opx==`IR_R_CALLR)|| (IR_opx==`IR_R_JMP)||
(IR_opx==`IR_R_RET ) ) )
PC_d_sel = PC_d_sel_RA;
else
PC_d_sel = PC_d_sel_X;
// rIMM
rIMM_wr = 1'b0;
rIMM_d_sel = rIMM_d_sel_X;
// ALU
rALU_wr = 1'b0;
ALU_b_sel = ALU_b_sel_X;
ALU_op = ALU_OP_X;
//------ RFile ------//
if( is_unkown_instr( IR )==1'b0 )
begin
if( (IR_op == `IR_I_BEQ ) ||
(IR_op == `IR_I_BGE ) ||
(IR_op == `IR_I_BGEU) ||
(IR_op == `IR_I_BLT ) ||
(IR_op == `IR_I_BLTU) ||
(IR_op == `IR_I_BNE ) ||
(IR_op == `IR_I_BR ) ||
(IR_op == `IR_J_JMPI) ||
(IR_op == `IR_I_STB ) ||
(IR_op == `IR_I_STH ) ||
(IR_op == `IR_I_STW ) ||
((IR_IsRType==1'b1)&&( (IR_opx==`IR_R_JMP) ||
(IR_opx==`IR_R_RET) ))
)
RFile_Cwr = 1'b0;
else
RFile_Cwr = 1'b1;
end
else
RFile_Cwr = 1'b0;
// R-type instruction
unique if( IR_IsRType==1'b1 )
if( IR_opx == `IR_R_CALLR )
RFile_Cidx_sel = RFile_Cidx_sel_RA;
else
RFile_Cidx_sel = RFile_Cidx_sel_IR_C;
// I-type instruction
else if( IR_IsIType==1'b1 )
RFile_Cidx_sel = RFile_Cidx_sel_IR_B;
// J-type instruction
else if( IR_IsJType==1'b1 )
RFile_Cidx_sel = RFile_Cidx_sel_RA;
else
RFile_Cidx_sel = RFile_Cidx_sel_IR_C;
unique if( ( (IR_IsRType==1'b1)&&( (IR_opx==`IR_R_CALLR ) ||
(IR_opx==`IR_R_NEXTPC) ) ) ||
(IR_op == `IR_J_CALL ) )
RFile_Cd_sel = RFile_Cd_sel_PC;
else if( IR_op==`IR_I_LDB|| IR_op==`IR_I_LDBU ||
IR_op==`IR_I_LDH|| IR_op==`IR_I_LDHU ||
IR_op==`IR_I_LDW||
IR_op==`IR_I_LDBIO|| IR_op==`IR_I_LDBUIO ||
IR_op==`IR_I_LDHIO|| IR_op==`IR_I_LDHUIO ||
IR_op==`IR_I_LDWIO)
RFile_Cd_sel = RFile_Cd_sel_DMaster;
else
RFile_Cd_sel = RFile_Cd_sel_rALU;
end: decoding_for_StageWB
else
begin : decoding_for_StageIDLE
// PC
PC_wr = 1'b0;
PC_d_sel = PC_d_sel_X;
// rIMM
rIMM_wr = 1'b0;
rIMM_d_sel = rIMM_d_sel_X;
// ALU
ALU_b_sel = ALU_b_sel_X;
ALU_op = ALU_OP_X;
rALU_wr = 1'b0;
// Write back RFile
RFile_Cwr = 1'b0;
RFile_Cidx_sel = RFile_Cidx_sel_X;
RFile_Cd_sel = RFile_Cd_sel_X;
end : decoding_for_StageIDLE
end: control_signal_gen
///////////////////////////////////////////////////////////////////////////////
// -1: for Simulation
///////////////////////////////////////////////////////////////////////////////
`ifdef SIM
parameter STDIN = 32'H8000_0000;
parameter STDOUT = 32'H8000_0001;
parameter STDERR = 32'H8000_0002;
integer log_fid;
initial
begin
log_fid = $fopen("Kunlun_r_sc.log","w");
if( log_fid==0 )
begin
$fwrite(STDERR,"Eror: can not open file Kunlun_r_sc.log!!!\n");
$finish;
end
end
integer clk_counter = 0;
integer instr_counter = 0;
integer fetch_cycle_count = 0;
always @( posedge clk, negedge rst_n )
begin
if ( ~rst_n )
clk_counter <= 0;
else begin
clk_counter <= #1 clk_counter+1;
if ( cur_stage==S_WB && next_stage==S_FETCH )
begin
instr_counter <= instr_counter +1;
end
$fwrite(log_fid,"###### clock cycle: %0d ######\n",clk_counter);
$fwrite(STDOUT ,"-- %8d, ",clk_counter);
$fwrite(log_fid,"instruction counter: %0d, ", instr_counter);
// cur_stage, next_stage
$fwrite(log_fid,"current stage: %s, next stage: %s\n", cur_stage.name, next_stage.name );
// ------ PC ------//
if( (cur_stage==S_FETCH && next_stage==S_DECODE) || (cur_stage==S_WB) )
begin
$fwrite(log_fid,"*" );
if( PC_wr )
$fwrite(log_fid,"! " );
else
$fwrite(log_fid," " );
end
$fwrite(log_fid,"C: 32'H%08H, PC_wr: %d, PC_d_sel: %s, PC_d: 32'H%08H \n", PC,PC_wr,PC_d_sel.name, PC_d );
if( cur_stage==S_FETCH )
begin
$fwrite(log_fid,"*! " );
end
$fwrite(log_fid,"i_read: %d, i_waitrequest: %d, i_address: 32'H%08H, i_readdata: 32'H%08H\n",
i_read, i_waitrequest, i_address, i_readdata );
// ------ IR ------//
if( (cur_stage==S_FETCH) && (next_stage==S_DECODE) )
begin
$fwrite(log_fid,"*! " );
end
$fwrite(log_fid,"IR: 32'H%08H, IR_wr: %d, IR_d: 32'H%08H \n", IR,IR_wr,IR_d);
if( (cur_stage!=S_FETCH)&&(cur_stage!=S_IDLE) )
begin
disAS(log_fid , IR);
end
// ------ rA rB, rIMM ------ //
if( cur_stage==S_DECODE )
begin
$fwrite(log_fid,"*! " );
end
$fwrite(log_fid,"RFile_Aidx: %0d, RFile_Aq: 32'H%08H, rA: 32'H%08H \n", RFile_Aidx,RFile_Aq,rA);
if( cur_stage==S_DECODE )
begin
$fwrite(log_fid,"*! " );
end
$fwrite(log_fid,"RFile_Bidx: %0d, RFile_Bq: 32'H%08H, rB: 32'H%08H \n", RFile_Bidx,RFile_Bq,rB);
if( cur_stage==S_DECODE )
begin
$fwrite(log_fid,"*" );
if(rIMM_wr) $fwrite(log_fid,"! " );
else $fwrite(log_fid," " );
end
$fwrite(log_fid,"rIMM: 32'H%08H, rIMM_wr: %0d, rIMM_d_sel: %s, rIMM_d: 32'H%08H \n", rIMM,rIMM_wr,rIMM_d_sel.name, rIMM_d);
// -----------ALU---------------//
if( cur_stage==S_EXE )
begin
$fwrite(log_fid,"* " );
end
$fwrite(log_fid,"ALU_q: 32'H%08H, ALU_op: %s, ALU_a: 32'H%08H, ALU_b: 32'H%08H, ALU_b_sel: %s\n",
ALU_q, ALU_op.name, ALU_a, ALU_b, ALU_b_sel.name);
if( cur_stage==S_EXE )
begin
$fwrite(log_fid,"*" );
if(rALU_wr) $fwrite(log_fid,"! " );
else $fwrite(log_fid," " );
end
$fwrite(log_fid,"rALU_wr: %0d, rALU: 32'H%08H \n", rALU_wr, rALU);
// -----------MEM----------------//
if( cur_stage==S_MEM)
begin
$fwrite(log_fid,"*" );
if(d_read || d_write) $fwrite(log_fid,"! " );
else $fwrite(log_fid," " );
end
$fwrite(log_fid,"d_read: %0d, d_readdata: 32'H%08H, d_write: %0d, d_writedata: 32'H%08H, d_address: 32'H%08H, d_byteenable: 4'b%04b, d_waitrequest: %0d\n",
d_read, d_readdata,d_write,d_writedata,d_address, d_byteenable, d_waitrequest);
if( cur_stage==S_MEM)
begin
$fwrite(log_fid,"*" );
if(rDMasterIn_wr) $fwrite(log_fid,"! " );
else $fwrite(log_fid," " );
end
$fwrite(log_fid,"data_from_DMaster: 32'H%08H, rDMasterIn_wr: %0d, rDMasterIn: 32'H%08H \n", data_from_DMaster, rDMasterIn_wr, rDMasterIn);
// -----------WB----------------//
if( cur_stage==S_WB )
begin
$fwrite(log_fid,"*" );
if(RFile_Cwr ) $fwrite(log_fid,"! " );
else $fwrite(log_fid," " );
end
$fwrite(log_fid,"RFile_Cwr: %d, RFile_Cidx_sel: %s, RFile_Cidx: %0d, RFile_Cd_sel: %s, RFile_Cd: 32'H%08H\n",
RFile_Cwr, RFile_Cidx_sel.name, RFile_Cidx, RFile_Cd_sel.name, RFile_Cd );
$fwrite(log_fid,"RFile:\n");
$fwrite(log_fid," %08H, %08H, %08H, %08H, %08H, %08H, %08H, %08H\n",
RFile[ 0],RFile[ 1],RFile[ 2],RFile[ 3],
RFile[ 4],RFile[ 5],RFile[ 6],RFile[ 7] );
$fwrite(log_fid," %08H, %08H, %08H, %08H, %08H, %08H, %08H, %08H\n",
RFile[ 8],RFile[ 9],RFile[10],RFile[11],
RFile[12],RFile[13],RFile[14],RFile[15] );
$fwrite(log_fid," %08H, %08H, %08H, %08H, %08H, %08H, %08H, %08H\n",
RFile[16],RFile[17],RFile[18],RFile[19],
RFile[20],RFile[21],RFile[22],RFile[23] );
$fwrite(log_fid," %08H, %08H, %08H, %08H, %08H, %08H, %08H, %08H\n",
RFile[24],RFile[25],RFile[26],RFile[27],
RFile[28],RFile[29],RFile[30],RFile[31] );
$fwrite(log_fid,"\n\n");
end
end
`endif
///////////////////////////////////////////////////////////////////////////////
// Functions //
///////////////////////////////////////////////////////////////////////////////
function [31: 0] cmpge ( input [31: 0] A, input [31: 0] B );
begin
cmpge = (A[30: 0]>=B[30: 0]);
if ( (~A[31]) & B[31] ) cmpge = 32'd1;
if ( ( A[31]) & (~B[31]) ) cmpge = 32'd0;
end
endfunction
function is_unkown_instr( input [31: 0] ir );
begin
if ( (ir[5:0] == `IR_J_CALL ) ||
(ir[5:0] == `IR_J_JMPI ) ||
(ir[5:0] == `IR_I_LDBU ) ||
(ir[5:0] == `IR_I_ADDI ) ||
(ir[5:0] == `IR_I_STB ) ||
(ir[5:0] == `IR_I_BR ) ||
(ir[5:0] == `IR_I_LDB ) ||
(ir[5:0] == `IR_I_CMPGEI) ||
(ir[5:0] == `IR_I_LDHU ) ||
(ir[5:0] == `IR_I_ANDI ) ||
(ir[5:0] == `IR_I_STH ) ||
(ir[5:0] == `IR_I_BGE ) ||
(ir[5:0] == `IR_I_LDH ) ||
(ir[5:0] == `IR_I_CMPLTI) ||
//(ir[5:0] == `IR_I_INITDA) ||
(ir[5:0] == `IR_I_ORI ) ||
(ir[5:0] == `IR_I_STW ) ||
(ir[5:0] == `IR_I_BLT ) ||
(ir[5:0] == `IR_I_LDW ) ||
(ir[5:0] == `IR_I_CMPNEI) ||
//(ir[5:0] == `IR_I_FLUSHDA) ||
(ir[5:0] == `IR_I_XORI ) ||
(ir[5:0] == `IR_I_BNE ) ||
(ir[5:0] == `IR_I_CMPEQI) ||
//(ir[5:0] == `IR_I_LDBUIO) ||
(ir[5:0] == `IR_I_MULI ) ||
//(ir[5:0] == `IR_I_STBIO ) ||
(ir[5:0] == `IR_I_BEQ ) ||
//(ir[5:0] == `IR_I_LDBIO ) ||
(ir[5:0] == `IR_I_CMPGEUI) ||
//(ir[5:0] == `IR_I_LDHUIO ) ||
(ir[5:0] == `IR_I_ANDHI ) ||
//(ir[5:0] == `IR_I_STHIO ) ||
(ir[5:0] == `IR_I_BGEU ) ||
//(ir[5:0] == `IR_I_LDHIO ) ||
(ir[5:0] == `IR_I_CMPLTUI) ||
//(ir[5:0] == `IR_I_INITD )||
(ir[5:0] == `IR_I_ORHI )||
//(ir[5:0] == `IR_I_STWIO )||
(ir[5:0] == `IR_I_BLTU )||
//(ir[5:0] == `IR_I_LDWIO )||
//(ir[5:0] == `IR_I_RDPRS )||
//(ir[5:0] == `IR_I_FLUSHD )||
(ir[5:0] == `IR_I_XORHI )||
( (ir[5:0]==6'h3A)&&
(ir[16:11]==`IR_R_ERET )||
(ir[16:11]==`IR_R_ROLI )||
(ir[16:11]==`IR_R_ROL )||
//(ir[16:11]==`IR_R_FLUSHP)||
(ir[16:11]==`IR_R_RET )||
(ir[16:11]==`IR_R_NOR )||
//(ir[16:11]==`IR_R_MULXUU)||
(ir[16:11]==`IR_R_CMPGE )||
//(ir[16:11]==`IR_R_BRET )||
(ir[16:11]==`IR_R_ROR )||
//(ir[16:11]==`IR_R_FLUSHI)||
(ir[16:11]==`IR_R_JMP )||
(ir[16:11]==`IR_R_AND )||
(ir[16:11]==`IR_R_CMPLT )||
(ir[16:11]==`IR_R_SLLI )||
(ir[16:11]==`IR_R_SLL )||
//(ir[16:11]==`IR_R_WRPRS )||
(ir[16:11]==`IR_R_OR )||
//(ir[16:11]==`IR_R_MULXSU)||
(ir[16:11]==`IR_R_CMPNE )||
(ir[16:11]==`IR_R_SRLI )||
(ir[16:11]==`IR_R_SRL )||
(ir[16:11]==`IR_R_NEXTPC)||
(ir[16:11]==`IR_R_CALLR )||
(ir[16:11]==`IR_R_XOR )||
//(ir[16:11]==`IR_R_MULXSS)||
(ir[16:11]==`IR_R_CMPEQ )||
//(ir[16:11]==`IR_R_DIVU )||
//(ir[16:11]==`IR_R_DIV )||
//(ir[16:11]==`IR_R_RDCTL )||
(ir[16:11]==`IR_R_MUL )||
(ir[16:11]==`IR_R_CMPGEU)||
//(ir[16:11]==`IR_R_INITI )||
//(ir[16:11]==`IR_R_TRAP )||
//(ir[16:11]==`IR_R_WRCTL )||
(ir[16:11]==`IR_R_CMPLTU)||
(ir[16:11]==`IR_R_ADD )||
//(ir[16:11]==`IR_R_BREAK )||
//(ir[16:11]==`IR_R_SYNC )||
(ir[16:11]==`IR_R_SUB )||
(ir[16:11]==`IR_R_SRAI )||
(ir[16:11]==`IR_R_SRA ) )
)
is_unkown_instr = 1'b0;
else
is_unkown_instr = 1'b1;
end
endfunction
function [31: 0] cmplt ( input [31: 0] A, input [31: 0] B );
begin
cmplt = (A[30: 0]<B[30: 0]);
if ( ( A[31]) & (~B[31]) ) cmplt = 32'd1;
if ( (~A[31]) & B[31] ) cmplt = 32'd0;
end
endfunction
function [31: 0] rol ( input [31: 0] A, input [ 4: 0] B );
begin
case ( B )
5'h0 : rol = A;
5'h1 : rol = { A[30: 0], A[31] };
5'h2 : rol = { A[29: 0], A[31:30] };
5'h3 : rol = { A[28: 0], A[31:29] };
5'h4 : rol = { A[27: 0], A[31:28] };
5'h5 : rol = { A[26: 0], A[31:27] };
5'h6 : rol = { A[25: 0], A[31:26] };
5'h7 : rol = { A[24: 0], A[31:25] };
5'h8 : rol = { A[23: 0], A[31:24] };
5'h9 : rol = { A[22: 0], A[31:23] };
5'h10 : rol = { A[21: 0], A[31:22] };
5'h11 : rol = { A[20: 0], A[31:21] };
5'h12 : rol = { A[19: 0], A[31:20] };
5'h13 : rol = { A[18: 0], A[31:19] };
5'h14 : rol = { A[17: 0], A[31:18] };
5'h15 : rol = { A[16: 0], A[31:17] };
5'h16 : rol = { A[15: 0], A[31:16] };
5'h17 : rol = { A[14: 0], A[31:15] };
5'h18 : rol = { A[13: 0], A[31:14] };
5'h19 : rol = { A[12: 0], A[31:13] };
5'h20 : rol = { A[11: 0], A[31:12] };
5'h21 : rol = { A[10: 0], A[31:11] };
5'h22 : rol = { A[ 9: 0], A[31:10] };
5'h23 : rol = { A[ 8: 0], A[31: 9] };
5'h24 : rol = { A[ 7: 0], A[31: 8] };
5'h25 : rol = { A[ 6: 0], A[31: 7] };
5'h26 : rol = { A[ 5: 0], A[31: 6] };
5'h27 : rol = { A[ 4: 0], A[31: 5] };
5'h28 : rol = { A[ 3: 0], A[31: 4] };
5'h29 : rol = { A[ 2: 0], A[31: 3] };
5'h30 : rol = { A[ 1: 0], A[31: 2] };
5'h31 : rol = { A[ 0: 0], A[31: 1] };
endcase
end
endfunction
function [31: 0] ror ( input [31: 0] A, input [ 4: 0] B );
begin
case ( B )
5'h0 : ror = A;
5'h1 : ror = { A[ 0: 0], A[31: 1] };
5'h2 : ror = { A[ 1: 0], A[31: 2] };
5'h3 : ror = { A[ 2: 0], A[31: 3] };
5'h4 : ror = { A[ 3: 0], A[31: 4] };
5'h5 : ror = { A[ 4: 0], A[31: 5] };
5'h6 : ror = { A[ 5: 0], A[31: 6] };
5'h7 : ror = { A[ 6: 0], A[31: 7] };
5'h8 : ror = { A[ 7: 0], A[31: 8] };
5'h9 : ror = { A[ 8: 0], A[31: 9] };
5'h10 : ror = { A[ 9: 0], A[31:10] };
5'h11 : ror = { A[10: 0], A[31:11] };
5'h12 : ror = { A[11: 0], A[31:12] };
5'h13 : ror = { A[12: 0], A[31:13] };
5'h14 : ror = { A[13: 0], A[31:14] };
5'h15 : ror = { A[14: 0], A[31:15] };
5'h16 : ror = { A[15: 0], A[31:16] };
5'h17 : ror = { A[16: 0], A[31:17] };
5'h18 : ror = { A[17: 0], A[31:18] };
5'h19 : ror = { A[18: 0], A[31:19] };
5'h20 : ror = { A[19: 0], A[31:20] };
5'h21 : ror = { A[20: 0], A[31:21] };
5'h22 : ror = { A[21: 0], A[31:22] };
5'h23 : ror = { A[22: 0], A[31:23] };
5'h24 : ror = { A[23: 0], A[31:24] };
5'h25 : ror = { A[24: 0], A[31:25] };
5'h26 : ror = { A[25: 0], A[31:26] };
5'h27 : ror = { A[26: 0], A[31:27] };
5'h28 : ror = { A[27: 0], A[31:28] };
5'h29 : ror = { A[28: 0], A[31:29] };
5'h30 : ror = { A[29: 0], A[31:30] };
5'h31 : ror = { A[30: 0], A[31:31] };
endcase
end
endfunction
task disAS( input integer fid, input [31: 0] instr );
reg [ 5: 0] i_op;
reg [ 5: 0] i_imm5;
reg [ 5: 0] i_opx;
reg [ 5: 0] i_c;
reg [ 5: 0] i_b;
reg [ 5: 0] i_a;
reg [15: 0] i_imm16;
reg [25: 0] i_imm26;
reg R_flag;
reg I_flag;
reg J_flag;
begin
i_op = instr[ 5: 0];
i_imm5 = instr[10: 6];
i_opx = instr[16:11];
i_c = instr[21:17];
i_b = instr[26:22];
i_a = instr[31:27];
i_imm16= instr[21: 6];
i_imm26= instr[31: 6];
R_flag = ( i_op==6'h3A );
J_flag = ( (i_op==`IR_J_CALL) || (i_op==`IR_J_JMPI) );
I_flag = !( R_flag || J_flag );
$fwrite( fid, "Instruction: ");
if( R_flag==1'b1 ) // R-type Instruction
begin
case ( i_opx )
`IR_R_ROLI : $fwrite(fid," roli r%0d, r%0d, %0d\n",
i_c,i_a,i_imm5);
`IR_R_ROL : $fwrite(fid," rol r%0d, r%0d, r%0d\n",
i_c,i_a,i_b[4:0]);
`IR_R_RET : $fwrite(fid," ret \n");
`IR_R_NOR : $fwrite(fid," nor r%0d, r%0d, r%0d\n",
i_c,i_a,i_b);
`IR_R_CMPGE : $fwrite(fid," cmpge r%0d, r%0d, r%0d\n",
i_c,i_a,i_b);
`IR_R_ROR : $fwrite(fid," ror r%0d, r%0d, r%0d\n",
i_c,i_a,i_b[4:0]);
`IR_R_JMP : $fwrite(fid," jmp r%0d\n", i_a);
`IR_R_AND : $fwrite(fid," and r%0d, r%0d, r%0d\n",
i_c,i_a,i_b);
`IR_R_CMPLT : $fwrite(fid," cmplt r%0d, r%0d, r%0d\n",
i_c,i_a,i_b);
`IR_R_SLLI : $fwrite(fid," slli r%0d, r%0d, %0d\n",
i_c,i_a,i_imm5);
`IR_R_SLL : $fwrite(fid," sll r%0d, r%0d, r%0d\n",
i_c,i_a,i_b[4:0]);
`IR_R_OR : $fwrite(fid," or r%0d, r%0d, r%0d\n",
i_c,i_a,i_b);
`IR_R_CMPNE : $fwrite(fid," cmpne r%0d, r%0d, r%0d\n",
i_c,i_a,i_b);
`IR_R_SRLI : $fwrite(fid," srli r%0d, r%0d, %0d\n",
i_c,i_a,i_imm5);
`IR_R_SRL : $fwrite(fid," srl r%0d, r%0d, r%0d\n",
i_c,i_a,i_b[4:0]);
`IR_R_NEXTPC : $fwrite(fid," nextpc r%0d\n",i_c);
`IR_R_CALLR : $fwrite(fid," callr r%0d\n",i_a);
`IR_R_XOR : $fwrite(fid," xor r%0d, r%0d, r%0d\n",
i_c,i_a,i_b);
`IR_R_CMPEQ : $fwrite(fid," cmpeq r%0d, r%0d, r%0d\n",
i_c,i_a,i_b);
`IR_R_MUL : $fwrite(fid," mul r%0d, r%0d, r%0d\n",
i_c,i_a,i_b);
`IR_R_CMPGEU : $fwrite(fid," cmpgeu r%0d, r%0d, r%0d\n",
i_c,i_a,i_b);
`IR_R_CMPLTU : $fwrite(fid," cmpltu r%0d, r%0d, r%0d\n",
i_c,i_a,i_b);
`IR_R_ADD : $fwrite(fid," add r%0d, r%0d, r%0d\n",
i_c,i_a,i_b);
`IR_R_SUB : $fwrite(fid," sub r%0d, r%0d, r%0d\n",
i_c,i_a,i_b);
`IR_R_SRAI : $fwrite(fid," srai r%0d, r%0d, %0d\n",
i_c,i_a,i_imm5);
`IR_R_SRA : $fwrite(fid," sra r%0d, r%0d, r%0d\n",
i_c,i_a,i_b[4:0]);
`IR_R_DIV : $fwrite(fid," div r%0d, r%0d, r%0d\n",
i_c,i_a,i_b[4:0]);
default : $fwrite(fid," Unkown R-type Instruction\n");
endcase
end
else if( I_flag==1'b1 )
begin
case ( i_op )
`IR_I_LDBU : $fwrite(fid," ldbu r%0d, %0d(r%0d)\n",
i_b, $signed(i_imm16), i_a);
`IR_I_ADDI : $fwrite(fid," addi r%0d, r%0d, %0d\n",
i_b, i_a, $signed(i_imm16));
`IR_I_STB : $fwrite(fid," stb r%0d, %0d(r%0d)\n",
i_b, $signed(i_imm16), i_a);
`IR_I_BR : $fwrite(fid," br %0d\n", $signed(i_imm16));
`IR_I_LDB : $fwrite(fid," ldb r%0d, %0d(r%0d)\n",
i_b, $signed(i_imm16), i_a);
`IR_I_CMPGEI : $fwrite(fid," cmpgei r%0d, r%0d, %0d\n",
i_b, i_a, $signed(i_imm16));
`IR_I_LDHU : $fwrite(fid," ldhu r%0d, %0d(r%0d)\n",
i_b, $signed(i_imm16), i_a);
`IR_I_ANDI : $fwrite(fid," andi r%0d, r%0d, %0d\n",
i_b, i_a, i_imm16 );
`IR_I_STH : $fwrite(fid," sth r%0d, %0d(r%0d)\n",
i_b, $signed(i_imm16), i_a);
`IR_I_BGE : $fwrite(fid," bge r%0d, r%0d, %0d\n",
i_a, i_b, $signed(i_imm16));
`IR_I_LDH : $fwrite(fid," ldh r%0d, %0d(r%0d)\n",
i_b, $signed(i_imm16), i_a);
`IR_I_CMPLTI : $fwrite(fid," cmplti r%0d, r%0d, %0d\n",
i_b, i_a, $signed(i_imm16));
`IR_I_ORI : $fwrite(fid," ori r%0d, r%0d, %0d\n",
i_b, i_a, i_imm16 );
`IR_I_STW : $fwrite(fid," stw r%0d, %0d(r%0d)\n",
i_b, $signed(i_imm16), i_a);
`IR_I_BLT : $fwrite(fid," blt r%0d, r%0d, %0d\n",
i_a, i_b, $signed(i_imm16));
`IR_I_LDW : $fwrite(fid," ldw r%0d, %0d(r%0d)\n",
i_b, $signed(i_imm16), i_a);
`IR_I_CMPNEI : $fwrite(fid," cmpnei r%0d, r%0d, %0d\n",
i_b, i_a, $signed(i_imm16));
`IR_I_XORI : $fwrite(fid," xori r%0d, r%0d, %0d\n",
i_b, i_a, i_imm16 );
`IR_I_BNE : $fwrite(fid," bne r%0d, r%0d, %0d\n",
i_a, i_b, $signed(i_imm16));
`IR_I_CMPEQI : $fwrite(fid," cmpeqi r%0d, r%0d, %0d\n",
i_b, i_a, $signed(i_imm16));
`IR_I_LDBUIO : $fwrite(fid," ldbuio r%0d, %0d(r%0d)\n",
i_b, $signed(i_imm16), i_a);
`IR_I_MULI : $fwrite(fid," muli r%0d, r%0d, %0d\n",
i_b,i_a, $signed(i_imm16));
`IR_I_BEQ : $fwrite(fid," beq r%0d, r%0d, %0d\n",
i_a, i_b, $signed(i_imm16));
`IR_I_CMPGEUI: $fwrite(fid," cmpgeui r%0d, r%0d, %0d\n",
i_b, i_a, $signed(i_imm16));
`IR_I_ANDHI : $fwrite(fid," andhi r%0d, r%0d, %0d\n",
i_b, i_a, $signed(i_imm16));
`IR_I_BGEU : $fwrite(fid," bgeu r%0d, r%0d, %0d\n",
i_a, i_b, $signed(i_imm16));
`IR_I_CMPLTUI: $fwrite(fid," cmpltui r%0d, r%0d, %0d\n",
i_b, i_a, $signed(i_imm16));
`IR_I_ORHI : $fwrite(fid," orhi r%0d, r%0d, %0d\n",
i_b, i_a, i_imm16 );
`IR_I_BLTU : $fwrite(fid," bltu r%0d, r%0d, %0d\n",
i_a, i_b, $signed(i_imm16));
`IR_I_XORHI : $fwrite(fid," xorhi r%0d, r%0d, %0d\n",
i_b, i_a, i_imm16 );
default : $fwrite(fid," Unkown I-type Instruction\n");
endcase
end
else if( J_flag==1'b1 )
begin
case ( i_op )
`IR_J_CALL : $fwrite(fid," call %0d\n", {i_imm26,2'b00} );
`IR_J_JMPI : $fwrite(fid," jmpi %0d\n", {i_imm26,2'b00} );
default : $fwrite(fid," Unkown J-type Instruction\n");
endcase
end
else
begin
$fwrite(fid," Unkown J-type Instruction\n");
end
end
endtask
endmodule |
|