1|`include "define.h"
2|
3|module cpu_core(input clock,
4| input sync_reset,
5| input ir_stall,data_stall,
6|
7|
8| input wire [31:0] ir_out,
9| input wire [31:0] data_fm_mem,
10| output wire [31:0] ir_addr,data_to_mem,
11| output wire [31:0] mem_addr,
12| output wire mem_read_req,
13| output wire mem_write_req,
14|
15| output wire mem_sign,
16| output wire [1:0] mem_access_mode,
17| input [5:0] interrupt,
18| output wire to_dcache_wait_req,
19| output wire ir_req,
20| output reg pre_rw_access, pre_read_access
21| );
22|
23|localparam [31:0] NOP_INSTRUCTION=0;
24|
25|localparam [4:0] R31=5'b11111;
26|localparam [5:0] SPECIAL=6'b000_000,BCOND=6'b00_001,
27| COP0=6'b010_000,
28| J=6'b000_010,JAL=6'b000_011,BEQ=6'b000_100,BNE=6'b000_101,BLEZ=6'b000_110,BGTZ=6'b000_111;
29|localparam [5:0] JR=6'b001_000,JALR=6'b001_001,SYSCALL=6'b001_100,BREAK=6'b001_101,
30| MTHI=6'b010_001,MTLO=6'b010_011;
31|localparam [31:0] General_Exception=`General_Exception;
32|
33|localparam [5:0] MULT =6'b011_000, MULTU=6'b011_001, DIV=6'b011_010, DIVU=6'b011_011;
34|
35|localparam [4:0] Status_Address=12, Cause_Address=13, EPC_Address=14;
36|localparam [5:0] StoreByte=`storebyte,StoreWord=`storeword,StoreLong=`storelong,
37| LoadLong=`loadlong, LoadWordUnsigned=`loadword_unsigned, LoadWordSigned=`loadword_signed,
38| LoadByteSigned=`loadbyte_signed,LoadByteUnsigned=`loadbyte_unsigned;
39|
40|
41|
42|localparam [1:0] RF_ALU_sel= `RF_ALU_sel,
43| RF_Shifter_sel=`RF_Shifter_sel,
44| RF_PC_SEL=`RF_PC_SEL,
45| SHIFT16_SEL=`SHIFT16_SEL;
46|
47|localparam [4:0] MF=5'b000_00,MT=5'b001_00;
48|
49|localparam [4:0] RFE=5'b10_000;
50|
51|reg [31:0] PC;
52|
53|
54|reg [31:0] IR;
55|
56|
57|reg [31:0] IR_LR;
58|reg [31:0] Sreg,Treg;
59|reg rf_write_lr;
60|reg [4:0] rf_dest_addr_lr;
61|reg [1:0] A_Right_Sel_lr;
62|
63|
64|wire mul_div_finished;
65|wire mul_div_start;
66|
67|reg [31:0] AReg;
68|reg [31:0] IR_A;
69|reg rf_write_a;
70|reg [4:0] rf_dest_addr_a;
71|wire [31:0] AReg_input;
72|
73|
74|
75|
76|
77|wire mul_div_stall;
78|wire int_mask_by_mul_div_execute=mul_div_stall;
79|wire dstall=mul_div_stall | data_stall | ir_stall;
80|assign ir_req=!(mul_div_stall | data_stall);
81|assign to_dcache_wait_req=mul_div_stall | ir_stall;
82|
83|
84|wire exception_command;
85|wire exeption_rise;
86|
87|
88|wire [4:0] target_addr=dstall ? IR[20:16] : ir_out[20:16];
89|wire [4:0] source_addr=dstall ? IR[25:21] : ir_out[25:21];
90|wire [31:0] rf_input,rf_target_out,rf_source_out;
91|wire [4:0] rf_write_addr;
92|
93|
94|
95|wire [31:0] alu_source,alu_target;
96|
97|
98|wire [31:0] shift_out;
99|wire [4:0] shifts=IR_LR[10:6];
100|
101|
102|wire taken;
103|wire jumpQ,jumpReg;
104|
105|
106|
107|reg [31:0] EPC;
108|reg KUo,IEo,KUp,IEp,KUc,IEc;
109|reg [7:0] IntMask;
110|reg BD;
111|reg [5:0] IP;
112|reg [1:0] Sw;
113|reg [3:0] ExeCode;
114|
115|
116|
117|
118|reg [7:0] int_old;
119|wire int_rise;
120|wire int_recog;
121|
122|
123|wire [4:0] copro_read_address=IR_LR[15:11];
124|wire [4:0] copro_write_address=IR_A[15:11];
125|
126|wire [31:0] status_reg={16'h0,IntMask,2'b00, KUo,IEo,KUp,IEp,KUc,IEc};
127|wire [31:0] cause_reg={BD,15'h0,IP,Sw,2'b00,ExeCode,2'b00};
128|wire [31:0] copro_output=copro_read_address==Status_Address ? status_reg :
129| copro_read_address==Cause_Address ? cause_reg :EPC;
130|wire cop_write=!dstall && IR_A[31:26]==COP0 && IR_A[25:21]==MT;
131|
132|
133|
134|wire [7:0] ints={ IP,Sw} & IntMask & {8{IEc}};
135|always @(posedge clock) begin
136| if (sync_reset) int_old<=8'h0;
137| else if (int_recog) int_old<=ints;
138|end
139|
140| assign int_rise=( ints & int_old ) ==0 &&
141| ints !=0;
142|
143|assign int_recog=int_rise && !dstall;
144|
145|assign exception_command=!dstall &&
146| (ir_out[31:26]==SPECIAL && ( ir_out[5:0]==SYSCALL || ir_out[5:0]==BREAK));
147|
148|always @(posedge clock) begin
149| if (sync_reset) IP<=0;
150| else IP<=interrupt;
151|end
152|
153|wire delayed_slot_processing=IR[31:26]==BCOND ||
154| IR[31:26]==J ||
155| IR[31:26]==JAL ||
156| IR[31:26]==BEQ ||
157| IR[31:26]==BNE ||
158| IR[31:26]==BLEZ ||
159| IR[31:26]==BGTZ ||
160| (IR [31:26]==SPECIAL && ( IR[5:0]==JR || IR[5:0]==JALR)) ;
161|
162|always @(posedge clock) begin
163| if (sync_reset) EPC<=0;
164| else if (int_recog || exception_command) begin
165| if (delayed_slot_processing) EPC<=PC-4;
166| else EPC<=PC;
167| end
168| else if (copro_write_address==EPC_Address && cop_write) EPC<=rf_input;
169|end
170|
171|
172|
173|always @(posedge clock) begin
174| if (sync_reset) IntMask<=0;
175| else if (copro_write_address==Status_Address && cop_write) IntMask<=rf_input[15:8];
176|end
177|
178|wire rfe_command=!dstall && (ir_out[31:26]==COP0 && ir_out[25] && ir_out[4:0]==RFE);
179|
180|always @(posedge clock) begin
181| if (sync_reset) {KUo,IEo,KUp,IEp,KUc,IEc}<=0;
182| else if (int_recog || exception_command) begin
183| {KUo,IEo,KUp,IEp,KUc,IEc}<={KUp,IEp,KUc,IEc,2'b00};
184| end
185| else if (rfe_command) begin
186| {KUo,IEo,KUp,IEp,KUc,IEc}<={KUo,IEo,KUo,IEo,KUp,IEp};
187| end
188|end
189|
190|always @(posedge clock) begin
191| if (sync_reset) Sw<=0;
192| else if (copro_write_address==Cause_Address && cop_write) begin
193| Sw<=rf_input[9:8];
194| end
195|end
196|
197|always @(posedge clock) begin
198| if (sync_reset) BD<=0;
199| else if (int_recog || exception_command) begin
200| if (delayed_slot_processing) BD<=1;
201| else BD<=0;
202| end
203|end
204|
205|
206|reg [1:0] mul_div_machine;
207|
208|
209|
210|
211|localparam [1:0] MUL_DIV_RESET=2'b00,
212| MUL_DIV_START=2'b01,
213| MUL_DIV_EXECUTING=2'b11,
214| MUL_DIV_FINISHED=2'b10;
215|
216|wire mul_div_command=IR[31:26]==SPECIAL &&
217| (IR[5:0]==MULT ||
218| IR[5:0]==MULTU ||
219| IR[5:0]==DIV ||
220| IR[5:0]==DIVU) && !ir_stall && !data_stall;
221|
222|always @(posedge clock) begin
223| if (sync_reset) mul_div_machine <=0;
224| else begin
225| case (mul_div_machine)
226| MUL_DIV_RESET: if (mul_div_command ) mul_div_machine <=MUL_DIV_START;
227| MUL_DIV_START: mul_div_machine <=MUL_DIV_EXECUTING;
228| MUL_DIV_EXECUTING: if(mul_div_finished) mul_div_machine <=MUL_DIV_FINISHED;
229| MUL_DIV_FINISHED: if (!ir_stall && !data_stall) mul_div_machine <=MUL_DIV_RESET;
230| endcase
231| end
232|end
233| assign mul_div_stall=mul_div_machine[0] && !mul_div_finished ;
234| assign mul_div_start=mul_div_machine==MUL_DIV_START;
235|
236| wire mul_div_high_write=!dstall && IR_LR[31:26]==SPECIAL && IR_LR[5:0]==MTHI;
237| wire mul_div_low_write=!dstall && IR_LR[31:26]==SPECIAL && IR_LR[5:0]==MTLO;
238|
239|
240|
241|reg [31:0] pc_decoder;
242|
243|always @* begin
244| if (sync_reset) pc_decoder=`Reset_Vector;
245| else if (dstall) pc_decoder=PC;
246| else if (int_recog || exception_command) pc_decoder=General_Exception;
247|
248| else if (0 ) pc_decoder=PC;
249| else if (taken) pc_decoder=PC+{{14 {IR[15]}},IR[15:0],2'b00};
250| else if (jumpQ) pc_decoder={PC[31:28], IR[25:0],2'b00};
251| else if (jumpReg) pc_decoder= rf_source_out;
252| else pc_decoder=PC+4;
253|end
254|
255|assign ir_addr=pc_decoder;
256|always @(posedge clock) begin
257| PC<=pc_decoder;
258|end
259|
260|
261|
262|reg [31:0] pc_d,pc_dd;
263|
264|
265|
266|
267|
268|
269|
270|
271|always @(posedge clock) begin
272| if (sync_reset) IR<=NOP_INSTRUCTION;
273| else if (dstall);
274| else if ( int_recog) IR<=NOP_INSTRUCTION;
275| else IR<=ir_out;
276|end
277|
278|
279|
280|
281|
282|
283| wire [31:0] qa,qb;
284|gen_ram32x32 ram_regfile32xx32 (
285| .data(rf_input),
286| .wraddress(rf_write_addr),
287| .rdaddress_a(target_addr),
288| .rdaddress_b(source_addr),
289| .wren(rf_write_a),
290| .clock(clock),
291| .qa(qa),
292| .qb(qb),.stall(dstall),.sync_reset(sync_reset));
293|
294|
295|always @(posedge clock) if (!dstall )pc_d<=pc_decoder+4;
296|
297|wire [5:0] opcode_ir=IR[31:26];
298|wire [5:0] opfunc_ir=IR[5:0];
299|
300|
301|
302|wire beqQ=opcode_ir==BEQ;
303|wire bneQ=opcode_ir ==BNE;
304|wire bgtzQ=opcode_ir==BGTZ;
305|wire blezQ=opcode_ir==BLEZ;
306|
307|
308|
309|localparam [20:16] BLTZ=5'b00_000,
310| BGEZ=5'b00_001,
311| BLTZAL=5'b10_000,
312| BGEZAL=5'b10_001;
313|
314|wire bgezQ=opcode_ir==BCOND && IR[20:16]==BGEZ;
315|wire bltzQ= opcode_ir==BCOND && IR[20:16]==BLTZ;
316|wire bltzalQ= opcode_ir==BCOND && IR[20:16]== BLTZAL;
317|wire bgezalQ= opcode_ir==BCOND && IR[20:16]== BGEZAL;
318|
319|
320|
321|
322|
323| assign jumpReg=opcode_ir==SPECIAL && (opfunc_ir==JR || opfunc_ir==JALR);
324| assign jumpQ =opcode_ir==JAL || opcode_ir==J;
325|
326|wire reg_compare= rf_target_out==rf_source_out;
327| assign taken= ( beqQ && reg_compare) ||
328| ( bneQ && !reg_compare) ||
329| ( bgtzQ && ( !rf_source_out[31] && !reg_compare)) ||
330| ( blezQ && (rf_source_out[31] || reg_compare )) ||
331| ( (bgezQ| bgezalQ) && (!rf_source_out[31])) ||
332| ( (bltzQ| bltzalQ) && ( rf_source_out[31] ));
333|
334|
335| reg [1:0] A_Right_SELD1;
336| always @ (*) begin
337| casex (opcode_ir)
338| StoreByte: A_Right_SELD1 =`A_RIGHT_ERT;
339| StoreWord: A_Right_SELD1 =`A_RIGHT_ERT;
340| StoreLong: A_Right_SELD1 =`A_RIGHT_ERT;
341| `andi : A_Right_SELD1 =`Imm_unsigned ;
342| `addi : A_Right_SELD1 =`Imm_signed ;
343| `addiu : A_Right_SELD1 =`Imm_signed;
344| `ori : A_Right_SELD1 =`Imm_unsigned;
345| `xori : A_Right_SELD1 =`Imm_unsigned;
346|
347| `beq : A_Right_SELD1 =`A_RIGHT_ERT;
348| `bgtz : A_Right_SELD1 =`A_RIGHT_ERT;
349| `blez : A_Right_SELD1 =`A_RIGHT_ERT;
350| `bne : A_Right_SELD1 =`A_RIGHT_ERT;
351|
352|
353| `comp_im_signed : A_Right_SELD1 =`Imm_signed;
354| `comp_im_unsigned : A_Right_SELD1 =`Imm_signed;
355|
356| 6'b00_000?:
357| case (opfunc_ir)
358|
359| default : A_Right_SELD1 =`A_RIGHT_ERT;
360| endcase
361| default: A_Right_SELD1 =`Imm_signed;
362| endcase
363| end
364|
365|
366| assign rf_target_out= (rf_dest_addr_lr==IR[20:16] && rf_write_lr && A_Right_SELD1==`A_RIGHT_ERT) ? AReg_input :
367| (rf_dest_addr_a==IR[20:16] && rf_write_a && A_Right_SELD1==`A_RIGHT_ERT) ? rf_input : qa;
368|
369| assign rf_source_out=(rf_dest_addr_lr==IR[25:21] && rf_write_lr ) ? AReg_input :
370| (rf_dest_addr_a==IR[25:21] && rf_write_a) ? rf_input : qb;
371|
372|
373|
374|
375|
376| always @(posedge clock) begin
377| if (sync_reset) IR_LR<=NOP_INSTRUCTION;
378| else if (!dstall) IR_LR<=IR;
379| end
380|
381|
382| always @ (posedge clock) begin
383| if (sync_reset) rf_write_lr<=0;
384| else if (dstall);
385| else
386| case (opcode_ir)
387| LoadByteSigned : rf_write_lr <=1'b1;
388| LoadByteUnsigned : rf_write_lr <=1'b1;
389| LoadWordSigned : rf_write_lr <=1'b1;
390| LoadWordUnsigned : rf_write_lr <=1'b1;
391| LoadLong : rf_write_lr <=1'b1;
392| `jump_and_link_im: rf_write_lr <=1'b1;
393| COP0: begin
394| case (IR_LR[25:21])
395| MF: rf_write_lr<=1'b1;
396| default: rf_write_lr<=1'b0;
397| endcase
398| end
399|
400| 6'b00_0000:
401| case (opfunc_ir)
402|
403| `divs: rf_write_lr<=1'b0;
404| `divu: rf_write_lr<=1'b0;
405| `muls: rf_write_lr<=1'b0;
406| `mulu: rf_write_lr<=1'b0;
407| default: rf_write_lr <=1'b1;
408| endcase
409| `andi : rf_write_lr <=1'b1;
410| `addi : rf_write_lr <=1'b1 ;
411| `addiu : rf_write_lr <=1'b1;
412| `ori : rf_write_lr <=1'b1;
413| `xori : rf_write_lr <=1'b1;
414| `lui : rf_write_lr <=1'b1;
415| `comp_im_signed : rf_write_lr <=1'b1;
416| `comp_im_unsigned : rf_write_lr <=1'b1;
417| default: rf_write_lr <=1'b0;
418| endcase
419| end
420|
421|
422|
423| always @(posedge clock) begin
424| if (sync_reset) Sreg<=0;
425| else if (!(dstall)) Sreg<=rf_source_out;
426| end
427|
428|
429| always @(posedge clock) begin
430| if (sync_reset) Treg<=0;
431| else if (!dstall) begin
432| case (A_Right_SELD1)
433| `Imm_signed : Treg<={ {16{IR[15]}},IR[15:0]};
434| `Imm_unsigned : Treg<={ 16'h000,IR[15:0]};
435| `A_RIGHT_ERT : Treg<=rf_target_out;
436| `IMM_26_SEL: Treg<={6'b00_0000,IR[25:0]};
437| default : Treg<={ {16{IR[15]}},IR[15:0]};
438| endcase
439| end
440| end
441|
442|
443| always @(posedge clock) if (!dstall) pc_dd<=pc_d;
444|
445|
446| reg [1:0] RF_input_addr_selD1;
447| always @ (*) begin
448| case (opcode_ir)
449| `andi : RF_input_addr_selD1=`RF_Ert_sel;
450| `addi : RF_input_addr_selD1 =`RF_Ert_sel;
451| `ori : RF_input_addr_selD1 =`RF_Ert_sel;
452| `xori : RF_input_addr_selD1=`RF_Ert_sel;
453| `jump_and_link_im: RF_input_addr_selD1=`RF_R15_SEL;
454| `lui : RF_input_addr_selD1 =`RF_Ert_sel;
455| `comp_im_signed : RF_input_addr_selD1 =`RF_Ert_sel;
456| `comp_im_unsigned: RF_input_addr_selD1=`RF_Ert_sel;
457| 6'b00_0000:
458| case (opfunc_ir)
459| `jump_and_link_register: RF_input_addr_selD1=`RF_R15_SEL;
460|
461| default : RF_input_addr_selD1=`RF_Erd_sel;
462| endcase
463| default: RF_input_addr_selD1=`RF_Ert_sel;
464| endcase
465| end
466|
467| always @ (posedge clock) begin
468| if(sync_reset) rf_dest_addr_lr<=0;
469| else if (dstall);
470| else
471| case (RF_input_addr_selD1)
472| `RF_Ert_sel: rf_dest_addr_lr <= IR[20:16];
473| `RF_Erd_sel: rf_dest_addr_lr <=IR[15:11];
474| `RF_R15_SEL: rf_dest_addr_lr <=R31;
475|
476| default : rf_dest_addr_lr <= IR[20:16];
477| endcase
478| end
479|
480|
481|
482| reg [2:0] alu_out_sel;
483| reg mul_div_result_read,copro_read;
484| reg shift_reg_sel;
485| reg [1:0] shift_func_sel;
486| reg [3:0] alu_func_sel;
487|
488| wire [4:0] nshift;
489| wire [31:0] alu_out;
490|
491|
492| wire mul_div_sign;
493| wire mul_div_div_select;
494| wire [31:0] c_mult;
495| wire mul_div_lohi_select;
496|
497| always @(posedge clock) begin
498| if (sync_reset) A_Right_Sel_lr<=`Imm_signed;
499| else if(!dstall) A_Right_Sel_lr<=A_Right_SELD1;
500| end
501|
502|
503| assign alu_source=Sreg;
504| assign alu_target= Treg;
505|
506|alu alu1(.a(alu_source),.b(alu_target),.alu_func(alu_func_sel),.alu_out(alu_out));
507|
508|
509|shifter sh1(.a(alu_target),.shift_out(shift_out),.shift_func(shift_func_sel),
510| .shift_amount(nshift));
511|
512|
513|assign nshift=shift_reg_sel ? alu_source[4:0] : shifts;
514|
515|
516|
517|mul_div MulDiv(.clock(clock),.sync_reset(sync_reset),.a(alu_source),.b(alu_target),
518| .mul_div_out(c_mult),.mul_div_sign(mul_div_sign),
519| .mul_div_mode(mul_div_div_select),
520| .mul_div_finished(mul_div_finished),.mul_div_start(mul_div_start),.lohi_select(mul_div_lohi_select),
521| .rf_input(Sreg),.high_write(mul_div_high_write),.low_write(mul_div_low_write));
522|
523|
524|
525|assign mul_div_div_select=IR_LR[1];
526|assign mul_div_sign=!IR_LR[0];
527|assign mul_div_lohi_select=IR_LR[1];
528|
529|
530|wire [31:0] w_mem_addr=alu_source+{ {16{IR_LR[15]}},IR_LR[15:0]};
531|wire [31:0] pre_mem_addr=rf_source_out+{ {16{IR[15]}},IR[15:0]};
532|
533|
534|wire [31:0] w_data_to_mem=alu_target;
535|
536|
537|
538|
539| assign mem_addr= pre_mem_addr;
540|
541|`ifdef BYTE_IN_CPU_CORE
542| wire [7:0] dport0,dport1,dport2,dport3;
543|
544| assign dport0=w_data_to_mem[7:0] ;
545| assign dport1=mem_access_mode !=`BYTE_ACCESS ? w_data_to_mem[15:8] :w_data_to_mem[7:0];
546| assign dport2=mem_access_mode==`LONG_ACCESS ? w_data_to_mem[23:16] : w_data_to_mem[7:0];
547| assign dport3=mem_access_mode==`LONG_ACCESS ? w_data_to_mem[31:24] :
548| mem_access_mode==`WORD_ACCESS ? w_data_to_mem[15:8] : w_data_to_mem[7:0];
549|
550| assign data_to_mem={dport3,dport2,dport1,dport0};
551|`else
552| assign data_to_mem= w_data_to_mem;
553|
554|`endif
555|
556| wire [5:0] opcode_ir_lr=IR_LR[31:26];
557| wire [5:0] opfunc_ir_lr=IR_LR[5:0];
558|
559| always @ (*) begin
560| case (opcode_ir_lr)
561| 6'b00_0000:
562| case (opfunc_ir_lr)
563| `lsl : shift_func_sel=`SHIFT_LEFT;
564| `sllv : shift_func_sel =`SHIFT_LEFT;
565| `asr : shift_func_sel=`SHIFT_RIGHT_SIGNED;
566| `srav : shift_func_sel=`SHIFT_RIGHT_SIGNED;
567| `lsr : shift_func_sel =`SHIFT_RIGHT_UNSIGNED;
568| `srlv : shift_func_sel=`SHIFT_RIGHT_UNSIGNED;
569| default : shift_func_sel=`SHIFT_LEFT;
570| endcase
571| default: shift_func_sel=`SHIFT_LEFT;
572| endcase
573| end
574|
575| always @ (*) begin
576| case (opcode_ir_lr)
577| `lui : begin
578| alu_out_sel =`SHIFT16_SEL;
579| shift_reg_sel=`SHIFT_AMOUNT_IMM_SEL;
580| mul_div_result_read=0;
581| copro_read=0;
582| end
583| `jump_and_link_im:
584| begin
585| alu_out_sel =`RF_PC_SEL;
586| shift_reg_sel=`SHIFT_AMOUNT_IMM_SEL;
587| mul_div_result_read=0;
588| copro_read=0;
589| end
590| COP0: begin
591| case (IR_LR[25:21])
592| MF:
593| begin
594| alu_out_sel=RF_PC_SEL;
595| shift_reg_sel=`SHIFT_AMOUNT_IMM_SEL;
596| mul_div_result_read=0;
597| copro_read=1;
598| end
599| default:
600| begin
601| alu_out_sel=RF_ALU_sel;
602| shift_reg_sel=`SHIFT_AMOUNT_IMM_SEL;
603| mul_div_result_read=0;
604| copro_read=0;
605| end
606| endcase
607| end
608| SPECIAL:
609| case (opfunc_ir_lr)
610| `jump_and_link_register :
611| begin
612| alu_out_sel=RF_PC_SEL;
613| shift_reg_sel=`SHIFT_AMOUNT_IMM_SEL;
614| mul_div_result_read=0;
615| copro_read=0;
616| end
617| `lsl , `asr , `lsr : begin
618| alu_out_sel=RF_Shifter_sel ;
619| shift_reg_sel=`SHIFT_AMOUNT_IMM_SEL;
620| mul_div_result_read=0;
621| copro_read=0;
622| end
623| `sllv, `srav , `srlv : begin
624| alu_out_sel=RF_Shifter_sel ;
625| shift_reg_sel=`SHIFT_AMOUNT_REG_SEL;
626| mul_div_result_read=0;
627| copro_read=0;
628| end
629|
630|
631|
632|
633| `mfhi , `mflo : begin
634| alu_out_sel=RF_PC_SEL;
635| shift_reg_sel=`SHIFT_AMOUNT_IMM_SEL;
636| mul_div_result_read=1;
637| copro_read=0;
638| end
639| default : begin
640| alu_out_sel=RF_ALU_sel;
641| shift_reg_sel=`SHIFT_AMOUNT_IMM_SEL;
642| mul_div_result_read=0;
643| copro_read=0;
644| end
645| endcase
646| default: begin
647| alu_out_sel=RF_ALU_sel;
648| shift_reg_sel=`SHIFT_AMOUNT_IMM_SEL;
649| mul_div_result_read=0;
650| copro_read=0;
651| end
652| endcase
653| end
654|
655| always @ (*) begin
656| case (opcode_ir_lr)
657| `andi : alu_func_sel =`ALU_AND;
658| `addi : alu_func_sel =`ALU_ADD ;
659| `addiu : alu_func_sel =`ALU_ADD;
660| `ori : alu_func_sel =`ALU_OR;
661| `xori : alu_func_sel =`ALU_XOR;
662| `comp_im_signed : alu_func_sel =`ALU_LESS_THAN_SIGNED;
663| `comp_im_unsigned : alu_func_sel =`ALU_LESS_THAN_UNSIGNED;
664| 6'b00_0000:
665| case (opfunc_ir_lr)
666| `add : alu_func_sel =`ALU_ADD ;
667| `addu : alu_func_sel=`ALU_ADD ;
668| `sub : alu_func_sel=`ALU_SUBTRACT;
669| `subu : alu_func_sel=`ALU_SUBTRACT;
670| `and : alu_func_sel=`ALU_AND;
671| `nor : alu_func_sel=`ALU_NOR;
672| `or : alu_func_sel=`ALU_OR;
673| `xor : alu_func_sel=`ALU_XOR;
674| `comp_signed : alu_func_sel=`ALU_LESS_THAN_SIGNED;
675| `comp_unsigned : alu_func_sel=`ALU_LESS_THAN_UNSIGNED;
676|
677| default : alu_func_sel=`ALU_NOTHING;
678| endcase
679| default: alu_func_sel=`ALU_NOTHING;
680| endcase
681| end
682|
683|
684| reg M_sign;
685| always @ (*) begin
686| case (opcode_ir_lr)
687| LoadByteSigned : M_sign=`M_signed;
688| LoadByteUnsigned : M_sign=`M_unsigned;
689| LoadWordSigned : M_sign=`M_signed;
690| LoadWordUnsigned : M_sign=`M_unsigned;
691| LoadLong : M_sign=`M_unsigned;
692| StoreByte: M_sign=`M_unsigned;
693| StoreWord: M_sign=`M_unsigned;
694| StoreLong: M_sign=`M_unsigned;
695| default: M_sign=`M_unsigned;
696| endcase
697| end
698|
699|
700|
701|
702|
703| reg [1:0] M_access_mode;
704| always @ (*) begin
705| case (opcode_ir_lr)
706| LoadByteSigned : M_access_mode=`BYTE_ACCESS;
707| LoadByteUnsigned : M_access_mode=`BYTE_ACCESS;
708| LoadWordSigned : M_access_mode=`WORD_ACCESS;
709| LoadWordUnsigned : M_access_mode=`WORD_ACCESS;
710| LoadLong : M_access_mode=`LONG_ACCESS;
711| StoreByte: M_access_mode=`BYTE_ACCESS;
712| StoreWord: M_access_mode=`WORD_ACCESS;
713| StoreLong: M_access_mode=`LONG_ACCESS;
714| default: M_access_mode=`LONG_ACCESS;
715| endcase
716| end
717|
718|
719| always @ (*) begin
720| case (opcode_ir)
721| LoadByteSigned : begin pre_rw_access=1; pre_read_access=1; end
722| LoadByteUnsigned : begin pre_rw_access=1;pre_read_access=1; end
723| LoadWordSigned : begin pre_rw_access=1;pre_read_access=1; end
724| LoadWordUnsigned : begin pre_rw_access=1;pre_read_access=1; end
725| LoadLong : begin pre_rw_access=1;pre_read_access=1; end
726| StoreByte: begin pre_rw_access=1;pre_read_access=0; end
727| StoreWord: begin pre_rw_access=1;pre_read_access=0; end
728| StoreLong: begin pre_rw_access=1;pre_read_access=0; end
729| default: begin pre_rw_access=0;pre_read_access=0; end
730| endcase
731| end
732|
733|
734| reg mem_write;
735|
736|
737|
738|
739|
740|
741|
742|
743|
744| always @ (*) begin
745| case (opcode_ir_lr)
746| StoreByte: mem_write=1'b1;
747| StoreWord: mem_write=1'b1;
748| StoreLong: mem_write=1'b1;
749| default: mem_write=1'b0;
750| endcase
751| end
752| assign mem_write_req= mem_write;
753|
754| assign mem_access_mode= M_access_mode;
755| assign mem_sign= M_sign;
756|
757|
758|
759|
760| always @(posedge clock) begin
761| if (sync_reset) IR_A<=NOP_INSTRUCTION;
762| else if (!dstall) IR_A<=IR_LR;
763| end
764|
765|
766| always @ (posedge clock) begin
767| if (sync_reset) rf_write_a<=0;
768| else if (!dstall) rf_write_a<=rf_write_lr;
769| end
770|
771|
772| assign AReg_input=dstall ? AReg :alu_out_sel==RF_ALU_sel ? alu_out :
773| alu_out_sel==RF_Shifter_sel ? shift_out :
774| alu_out_sel==SHIFT16_SEL ? {IR_LR[15:0],16'h00} :
775| mul_div_result_read ? c_mult :
776| copro_read ? copro_output :
777| pc_dd;
778| always @(posedge clock) begin
779| if (sync_reset) AReg<=0;
780| else AReg<=AReg_input;
781|
782| end
783|
784|
785| always @(posedge clock) begin
786| if (!dstall) rf_dest_addr_a<=rf_dest_addr_lr;
787|
788|
789| end
790|
791|
792| wire [5:0] opcode_ir_a=IR_A[31:26];
793| wire [5:0] opfunc_ir_a=IR_A[5:0];
794| wire target_sel;
795| wire r31_sel;
796|
797|
798|
799|
800|
801|
802|
803|
804|
805| assign mem_read_req= opcode_ir_a==LoadByteSigned ||
806| opcode_ir_a==LoadByteUnsigned ||
807| opcode_ir_a==LoadWordSigned ||
808| opcode_ir_a==LoadWordUnsigned ||
809| opcode_ir_a==LoadLong ;
810|
811|
812|
813|
814|`ifdef DEBUG
815| integer fi;
816| `ifdef REFERENCE_SIM
817| initial fi=$fopen("pc_file_ref.txt","w");
818| `else
819| initial fi=$fopen("pc_file.txt","w");
820| `endif
821|
822|
823| initial debug1.counter=0;
824| reg [31:0] load_address_ir,load_address_ir_lr,load_address_ir_a;
825|
826| always @(posedge clock) begin:debug1
827| integer counter;
828| integer i;
829|
830| if (~dstall & pre_rw_access) load_address_ir_lr<=pre_mem_addr;
831| if(!dstall) load_address_ir_a<=load_address_ir_lr;
832|
833|
834|
835| if (!dstall ) begin
836| $fdisplay(fi,"%6d PC=%8h IR=%8h ",counter,PC,IR);
837| counter<=counter+1;
838| `ifdef REG_DEBUG_OUT
839| for (i=0;i<=31;i=i+1) begin
840| $fwrite(fi,"R[%02h]=%h ",i,ram_regfile32xx32.mem[i]);
841| end
842| $fdisplay(fi,"");
843| `endif
844| end
845| if (mem_write_req && !dstall) begin
846| if (opcode_ir_lr==StoreByte ) $fdisplay(fi,"Store_Byte addr=%8h data=%2h",load_address_ir_lr,data_to_mem[7:0]);
847| else if (opcode_ir_lr==StoreWord ) $fdisplay(fi,"Store_Word addr=%8h data=%4h",load_address_ir_lr,data_to_mem[15:0]);
848| else $fdisplay(fi,"Store_Long addr=%8h data=%8h",load_address_ir_lr,data_to_mem[31:0]);
849|
850| end
851| if (mem_read_req && !dstall) begin
852| if (opcode_ir_a==LoadByteSigned ||
853| opcode_ir_a==LoadByteUnsigned ) $fdisplay(fi,"Load_Byte addr=%8h data=%2h",load_address_ir_a,data_fm_mem[7:0]);
854| else if (opcode_ir_a==LoadWordSigned ||
855| opcode_ir_a==LoadWordUnsigned
856| ) $fdisplay(fi,"Load_Word addr=%8h data=%4h",load_address_ir_a,data_fm_mem[15:0]);
857| else $fdisplay(fi,"Load_Long addr=%8h data=%8h",load_address_ir_a,data_fm_mem[31:0]);
858|
859| end
860|
861| end
862|
863|`include "disasm.v"
864|`endif
865| wire [31:0] areg_or_mem_out=mem_read_req ? data_fm_mem : AReg;
866| assign rf_input= areg_or_mem_out;
867|
868|
869| assign rf_write_addr=rf_dest_addr_a;
870|
871|
872|
873|
874|endmodule
875|
876|
877|