URL
https://opencores.org/ocsvn/yacc/yacc/trunk
Subversion Repositories yacc
[/] [yacc/] [trunk/] [rtl/] [pipelined_rfile.v] - Rev 4
Compare with Previous | Blame | View Log
//Jun.30.2004 Mux sentibity list bug fix //Jul.2.2004 Cleanup //Jul.7.2004 int bug fix //Jan.20.2005 apply @* `include "define.h" module Pipelined_RegFile(clock,sync_reset, dest_addrD2,source_addr,target_addr, wren,memory_wdata, A_Right_SELD1,A_Left_SELD1,PCD1,IMMD1,ALU_FuncD2,Shift_FuncD2, Shift_amountD2,RRegSelD1,MOUT,RF_inputD2,alu_source,alu_target, MWriteD2,MWriteD1,mul_alu_selD2,mul_div_funcD2,pause_out, Shift_Amount_selD2,int_stateD1,PCCDD ); parameter adder_type="GENERIC"; `ifdef RAM4K input [11:0] PCD1; `else input [25:0] PCD1; `endif input [15:0] IMMD1;//Jul.6.2004 input [4:0] dest_addrD2; input [4:0] source_addr; input [4:0] target_addr; input wren; input clock; input A_Left_SELD1; input [3:0] ALU_FuncD2; input [4:0] Shift_amountD2; input [1:0] Shift_FuncD2; input [1:0] A_Right_SELD1; input sync_reset; input [1:0] RRegSelD1; output [31:0] alu_target,alu_source; output [31:0] memory_wdata; input [31:0] MOUT; input [1:0] RF_inputD2; input MWriteD2,MWriteD1; input [1:0] mul_alu_selD2; input [3:0] mul_div_funcD2; output pause_out; input Shift_Amount_selD2; input int_stateD1; reg [31:0] AReg,NReg,RReg,DReg; reg [31:0] alu_left_latch,alu_right_latch; reg [31:0] memory_wdata; `ifdef RAM4K input [11:0] PCCDD; reg [11:0] PCD2; `else input [25:0] PCCDD; reg [25:0] PCD2; `endif reg [15:0] IMMD2;//Jul.6.2004 reg [4:0] dadrD3,dadrD4,dadrD5,dadrD6; reg [4:0] sadrD1,sadrD2; reg [4:0] tadrD1,tadrD2; reg WD3,WD4,WD5,WD6; reg [1:0] A_Right_SELD2; reg [1:0] RRegSelD2, RRegSelD3, RRegSelD4; reg [31:0] RRegin; reg test1D,test2D; wire [31:0] alu_right; reg [31:0] alu_left; wire [31:0] source_out,target_out; wire [31:0] alu_out,shift_out; wire [31:0] alu_source=alu_left; wire [31:0] alu_target=alu_right; wire [31:0] regfile_in; wire [31:0] test,test2; wire test1; reg stest1D,stest2D; reg stest1D_dup1,stest1D_dup2,stest1D_dup3,stest1D_dup4; reg [31:0] mul_alu_out; reg div_mode_ff; reg sign_ff; reg RRegSelD4_dup1,RRegSelD4_dup2,RRegSelD4_dup3; wire mul_div_enable,mul_div_sign,mul_div_mode; wire [31:0] mul_div_out; wire [31:0] c_mult; wire [4:0] Shift_Amount; localparam [4:0] zero_=0, at_=1, v0_=2, v1_=3, a0_=4, a1_=5, a2_=6, a3_=7, t0_=8, t1_=9,t2_=10,t3_=11,t4_=12,t5_=13,t6_=14,t7_=15, s0_=16,s1_=17,s2_=18,s3_=19,s4_=20,s5_=21,s6_=22,s7_=23,t8_=24,t9_=25, k0_=26,k1_=27,gp_=28,sp_=29,s8_=30,ra_=31; always @(posedge clock) begin dadrD3<=dest_addrD2; dadrD4<=dadrD3; dadrD5<=dadrD4; dadrD6<=dadrD5; tadrD1<=target_addr; tadrD2<=tadrD1; sadrD1<=source_addr; sadrD2<=sadrD1; if ( (mul_div_funcD2 ==4'b0000 ) || (mul_div_funcD2 ==4'b0001 ) || (mul_div_funcD2 ==4'b0010 ) ) WD3<=wren;//NOTHING,READLO/HI 以外ではライトを止める else WD3<=1'b0; WD4<=WD3; WD5<=WD4; WD6<=WD5; A_Right_SELD2<=A_Right_SELD1; IMMD2<=IMMD1; if (int_stateD1) PCD2<=PCCDD;//Jul.7.2004 else PCD2<=PCD1; RRegSelD2<=RRegSelD1; RRegSelD3<=RRegSelD2; RRegSelD4<=RRegSelD3; RRegSelD4_dup1<=RRegSelD3[0]; RRegSelD4_dup2<=RRegSelD3[0]; RRegSelD4_dup3<=RRegSelD3[0]; end //AReg always @(posedge clock) begin case (RF_inputD2) `RF_ALU_sel : AReg<=alu_out; `RF_Shifter_sel: AReg<=shift_out; `SHIFT16_SEL: AReg<= {IMMD2[15:0],16'h00}; `RF_PC_SEL : AReg<=mul_alu_out; endcase end //ARegSel always @(*) begin//Mar.5.2005 if (! mul_alu_selD2[1] ) mul_alu_out={6'b00_0000,PCD2}; else mul_alu_out=c_mult; end //NReg always @(posedge clock) NReg<=AReg; //RReg always @(posedge clock) begin case (RRegSelD4_dup1) `MOUT_SEL : RReg<=MOUT; `NREG_SEL: RReg<=NReg; default : RReg<=MOUT; endcase end //DReg always @(posedge clock) begin DReg<=RReg; end always @(*) begin case (RRegSelD4_dup2) `MOUT_SEL : RRegin=MOUT; `NREG_SEL: RRegin=NReg; default : RRegin=MOUT; endcase end //target_reg always @(*) memory_wdata=alu_right; mul_div MulDiv(.clock(clock),.sync_reset(sync_reset),.a(alu_left),.b(alu_right), .mul_div_out(c_mult),.mul_div_sign(mul_div_funcD2[1]), .mul_div_word(1'b1),.mul_div_mode(mul_div_funcD2[2]), .stop_state(pause_out),.mul_div_enable(mul_div_funcD2[3]),.lohi(mul_div_funcD2[0])); assign mul_div_enable= mul_div_funcD2; always @(posedge clock) begin if (sync_reset) div_mode_ff<=1'b0; else if (mul_div_enable) div_mode_ff<=mul_div_mode; end always @(posedge clock) begin if (sync_reset) sign_ff<=1'b0; else if (mul_div_enable) sign_ff<=mul_div_sign; end assign mul_div_mode=!(IMMD2[1] ==`MUL_DIV_MUL_SEL);//div high / mul low assign mul_div_sign=!IMMD2[0]; alu alu1(.a(alu_left),.b(alu_right),.alu_func(ALU_FuncD2),.alu_out(alu_out)); shifter sh1(.a(alu_right),.shift_out(shift_out),.shift_func(Shift_FuncD2), .shift_amount(Shift_Amount)); assign Shift_Amount=Shift_Amount_selD2==`SHIFT_AMOUNT_REG_SEL ? alu_left[4:0] : Shift_amountD2; //alu left latch always @(posedge clock) begin begin if (sadrD1==dadrD4 && WD4) alu_left_latch<=RRegin; //OK else if (sadrD1==dadrD5 && WD5) alu_left_latch<=RReg;//This must be priority encoder else if (sadrD1==dadrD6 && WD6) alu_left_latch<=DReg; else alu_left_latch<=source_out; end end //alu right latch always @(posedge clock) begin begin case (A_Right_SELD1) `Imm_signed : alu_right_latch<={ {16{IMMD1[15]}},IMMD1[15:0]}; `Imm_unsigned : alu_right_latch<={ 16'h000,IMMD1[15:0]}; `A_RIGHT_ERT : begin if (tadrD1==dadrD4 && WD4 ) alu_right_latch<=RRegin; else //OK if (tadrD1==dadrD5 && WD5 ) alu_right_latch<=RReg; else if (tadrD1==dadrD6 && WD6) alu_right_latch<=DReg; else alu_right_latch<=target_out; end `IMM_26_SEL : begin alu_right_latch<={6'b00_0000,IMMD1}; end default : alu_right_latch<={ {16{IMMD1[15]}},IMMD1[15:0]}; endcase end end `ifdef ALTERA ram_regfile32xx32 RFile( .data(regfile_in), .wraddress(dadrD5), .rdaddress_a(target_addr), .rdaddress_b(source_addr), .wren(WD5), .clock(clock), .qa(target_out), .qb(source_out)); `else ram32x32_xilinx RFile ( .data(regfile_in), .wraddress(dadrD5), .rdaddress_a(target_addr), .rdaddress_b(source_addr), .wren(WD5), .clock(clock), .qa(target_out), .qb(source_out)); `endif assign regfile_in=dadrD5==5'b0_0000 ? 32'h0000_0000 :RReg; always @* begin // case (stest1D_dup1) 1'b1: alu_left[7:0]=AReg[7:0]; 1'b0: case(stest2D) 1'b1: case (RRegSelD4_dup3) `MOUT_SEL : alu_left[7:0]=MOUT[7:0]; `NREG_SEL: alu_left[7:0]=NReg[7:0]; endcase 1'b0: alu_left[7:0]=alu_left_latch[7:0]; endcase endcase end always @* begin // case (stest1D_dup2) 1'b1: alu_left[15:8]=AReg[15:8]; 1'b0: case(stest2D) 1'b1: case (RRegSelD4_dup3) `MOUT_SEL : alu_left[15:8]=MOUT[15:8]; `NREG_SEL: alu_left[15:8]=NReg[15:8]; endcase 1'b0: alu_left[15:8]=alu_left_latch[15:8]; endcase endcase end always @* begin// case (stest1D_dup3) 1'b1: alu_left[23:16]=AReg[23:16]; 1'b0: case(stest2D) 1'b1: case (RRegSelD4_dup3) `MOUT_SEL : alu_left[23:16]=MOUT[23:16]; `NREG_SEL: alu_left[23:16]=NReg[23:16]; endcase 1'b0: alu_left[23:16]=alu_left_latch[23:16]; endcase endcase end always @* begin // case (stest1D_dup4) 1'b1: alu_left[31:24]=AReg[31:24]; 1'b0: case(stest2D) 1'b1: case (RRegSelD4_dup3) `MOUT_SEL : alu_left[31:24]=MOUT[31:24]; `NREG_SEL: alu_left[31:24]=NReg[31:24]; endcase 1'b0: alu_left[31:24]=alu_left_latch[31:24]; endcase endcase end assign alu_right=test1D ? AReg : test2D ? RRegin : alu_right_latch; always @(posedge clock) begin stest1D<=(sadrD1==dest_addrD2) && wren; stest1D_dup1<=(sadrD1==dest_addrD2) && wren; stest1D_dup2<=(sadrD1==dest_addrD2) && wren; stest1D_dup3<=(sadrD1==dest_addrD2) && wren; stest1D_dup4<=(sadrD1==dest_addrD2) && wren; end always @(posedge clock) begin stest2D<=(sadrD1==dadrD3) && WD3 ; end always @(posedge clock) begin test1D<=tadrD1==dest_addrD2 && (wren ) && A_Right_SELD1==`A_RIGHT_ERT; end always @(posedge clock) begin test2D<=tadrD1==dadrD3 && (WD3 ) && A_Right_SELD1==`A_RIGHT_ERT; end `ifdef Veritak reg [30*8:1] alu_function; reg [30*8:1] shift_function; reg [30*8:1] AReg_Input_Sel; always @*//Jan.20.2005 @(ALU_FuncD2,alu_left,alu_right) case (ALU_FuncD2) `ALU_NOTHING : $sprintf(alu_function,"non_operation"); `ALU_ADD : $sprintf(alu_function,"ADD %h,%h",alu_left,alu_right); `ALU_SUBTRACT :$sprintf(alu_function,"SUB %h,%h,alu_left,alu_right"); `ALU_LESS_THAN_UNSIGNED :$sprintf(alu_function ,"LT_Unsigned %h,%h",alu_left,alu_right); `ALU_LESS_THAN_SIGNED : $sprintf(alu_function,"LT_Signed %h,%h",alu_left,alu_right); `ALU_OR : $sprintf(alu_function,"OR %h,%h",alu_left,alu_right); `ALU_AND : $sprintf(alu_function,"XOR %h,%h,alu_left,alu_right"); `ALU_XOR : $sprintf(alu_function,"AND %h,%h",alu_left,alu_right); `ALU_NOR : $sprintf(alu_function,"NOR %h,%h",alu_left,alu_right); default: $sprintf(alu_function,"non_operation"); endcase always @* begin // case (Shift_FuncD2) `SHIFT_LEFT : $sprintf(shift_function,"SLL %d",Shift_Amount); `SHIFT_RIGHT_UNSIGNED : $sprintf(shift_function,"SLR %d",Shift_Amount); `SHIFT_RIGHT_SIGNED : $sprintf(shift_function,"SAR %d",Shift_Amount); default: $sprintf(shift_function,"non_operation"); endcase end always @* begin // case (RF_inputD2) `RF_ALU_sel : $sprintf(AReg_Input_Sel,"ALU"); `RF_Shifter_sel: $sprintf(AReg_Input_Sel,"Shifter"); `SHIFT16_SEL: $sprintf(AReg_Input_Sel,"IMM16<<16"); `RF_PC_SEL : $sprintf(AReg_Input_Sel,"PC/MulOutSEL"); endcase end `endif endmodule