📄 id.v
字号:
begin if (((need_2cycles & !load_use) | (load_use & !need_2cycles)) & id_enbar & !hold_next_ex) second <= ~second; else second <= 1'b0; end end//These next two blocks control the flip-flops that//make up the Register Mask used in LDM/STM instructions.//When AND'd together, these represent the registers left//to transfer.always @(ldm_stm or ir or next_reg_mask) begin if (!ldm_stm) reg_mask_a <= ir[15:0]; else reg_mask_a <= next_reg_mask; end always @(posedge nGCLK or negedge nRESET) begin if (!nRESET) ldm_stm <= 1'b0; else if (nWAIT) ldm_stm <= (ldm || stm) && id_enbar && !hold_next_ex; end//Remember whether last inst was a loadalways @(posedge nGCLK or negedge nRESET) begin if (!nRESET) ldr_ex <= 1'b0; else if (nWAIT) ldr_ex <= ldrh | ldrw; endalways @(posedge nGCLK or negedge nRESET) begin if (!nRESET) ldm_ex <= 1'b0; else if (nWAIT) ldm_ex <= ldm; end/*------------------------------------------------------------------------ Combinational Always Blocks------------------------------------------------------------------------*///Mux the inst_code/Exceptionalways @(inst_type or und) begin if (und) inst_type_id = `UND; else inst_type_id = inst_type; end//Mux the mode bits into the mapreg module//For some LDM/STM need to transfer USER regsalways @(ir or ldm or stm or ldm_stm or mode) begin if (!ldm_stm & ((!ir[15] & ir[22] & ldm) || (ir[22] & stm))) mode_user_a <= 5'b10000; else mode_user_a <= mode; end//Mux the mode bits into the mapreg module//For some LDM/STM need to transfer USER regsalways @(ir or ldm or stm or mode) begin if ((!ir[15] && ir[22] && ldm) || (ir[22] && stm)) mode_user_b <= 5'b10000; else mode_user_b <= mode; end//Mux the mode bits into the mapreg module//For some LDM/STM need to transfer USER regs//For exceptions, need to get correct link regalways @(mode_user_a or und or swi or exception_id or exc_code_id) begin if (exception_id) begin case (exc_code_id) //synopsys full_case parallel_case 2'b00, 2'b11: mode_user_Rn = 5'b10111; //D/I Abort 2'b01: mode_user_Rn = 5'b10001; //FIQ 2'b10: mode_user_Rn = 5'b10010; //IRQ endcase end else if (und) //Und Mode mode_user_Rn = 5'b11011; else if (swi) //SVC MOde mode_user_Rn = 5'b10011; else mode_user_Rn = mode_user_a; end//Calculate the number of multiples of 4 which will//be added or subtracted to from Rn to form the new//base value for LDM/STM instructions.integer i;integer count;always @(ldm or stm or ir) begin count = 0; if (ldm | stm) begin for (i = 0; i <= 15; i = i+1) begin count = count + ir[i]; end end end//Set up a Priority Encoder to find//Next LDM/STM Register in transferalways @(reg_mask_a) begin casex (reg_mask_a) //synopsys parallel_case 16'b0000000000000000: mreg_a = 4'h0; 16'b???????????????1: mreg_a = 4'h0; 16'b??????????????10: mreg_a = 4'h1; 16'b?????????????100: mreg_a = 4'h2; 16'b????????????1000: mreg_a = 4'h3; 16'b???????????10000: mreg_a = 4'h4; 16'b??????????100000: mreg_a = 4'h5; 16'b?????????1000000: mreg_a = 4'h6; 16'b????????10000000: mreg_a = 4'h7; 16'b???????100000000: mreg_a = 4'h8; 16'b??????1000000000: mreg_a = 4'h9; 16'b?????10000000000: mreg_a = 4'hA; 16'b????100000000000: mreg_a = 4'hB; 16'b???1000000000000: mreg_a = 4'hC; 16'b??10000000000000: mreg_a = 4'hD; 16'b?100000000000000: mreg_a = 4'hE; 16'b1000000000000000: mreg_a = 4'hF; endcase casex (reg_mask_a) //synopsys parallel_case 16'b0000000000000000, 16'b0000000000000001, 16'b0000000000000010, 16'b0000000000000100, 16'b0000000000001000, 16'b0000000000010000, 16'b0000000000100000, 16'b0000000001000000, 16'b0000000010000000, 16'b0000000100000000, 16'b0000001000000000, 16'b0000010000000000, 16'b0000100000000000, 16'b0001000000000000, 16'b0010000000000000, 16'b0100000000000000, 16'b1000000000000000: mreg_b = 4'h0; 16'b??????????????11: mreg_b = 4'h1; 16'b?????????????101, 16'b?????????????110: mreg_b = 4'h2; 16'b????????????1001, 16'b????????????1010, 16'b????????????1100: mreg_b = 4'h3; 16'b???????????10001, 16'b???????????10010, 16'b???????????10100, 16'b???????????11000: mreg_b = 4'h4; 16'b??????????100001, 16'b??????????100010, 16'b??????????100100, 16'b??????????101000, 16'b??????????110000: mreg_b = 4'h5; 16'b?????????1000001, 16'b?????????1000010, 16'b?????????1000100, 16'b?????????1001000, 16'b?????????1010000, 16'b?????????1100000: mreg_b = 4'h6; 16'b????????10000001, 16'b????????10000010, 16'b????????10000100, 16'b????????10001000, 16'b????????10010000, 16'b????????10100000, 16'b????????11000000: mreg_b = 4'h7; 16'b???????100000001, 16'b???????100000010, 16'b???????100000100, 16'b???????100001000, 16'b???????100010000, 16'b???????100100000, 16'b???????101000000, 16'b???????110000000: mreg_b = 4'h8; 16'b??????1000000001, 16'b??????1000000010, 16'b??????1000000100, 16'b??????1000001000, 16'b??????1000010000, 16'b??????1000100000, 16'b??????1001000000, 16'b??????1010000000, 16'b??????1100000000: mreg_b = 4'h9; 16'b?????10000000001, 16'b?????10000000010, 16'b?????10000000100, 16'b?????10000001000, 16'b?????10000010000, 16'b?????10000100000, 16'b?????10001000000, 16'b?????10010000000, 16'b?????10100000000, 16'b?????11000000000: mreg_b = 4'hA; 16'b????100000000001, 16'b????100000000010, 16'b????100000000100, 16'b????100000001000, 16'b????100000010000, 16'b????100000100000, 16'b????100001000000, 16'b????100010000000, 16'b????100100000000, 16'b????101000000000, 16'b????110000000000: mreg_b = 4'hB; 16'b???1000000000001, 16'b???1000000000010, 16'b???1000000000100, 16'b???1000000001000, 16'b???1000000010000, 16'b???1000000100000, 16'b???1000001000000, 16'b???1000010000000, 16'b???1000100000000, 16'b???1001000000000, 16'b???1010000000000, 16'b???1100000000000: mreg_b = 4'hC; 16'b??10000000000001, 16'b??10000000000010, 16'b??10000000000100, 16'b??10000000001000, 16'b??10000000010000, 16'b??10000000100000, 16'b??10000001000000, 16'b??10000010000000, 16'b??10000100000000, 16'b??10001000000000, 16'b??10010000000000, 16'b??10100000000000, 16'b??11000000000000: mreg_b = 4'hD; 16'b?100000000000001, 16'b?100000000000010, 16'b?100000000000100, 16'b?100000000001000, 16'b?100000000010000, 16'b?100000000100000, 16'b?100000001000000, 16'b?100000010000000, 16'b?100000100000000, 16'b?100001000000000, 16'b?100010000000000, 16'b?100100000000000, 16'b?101000000000000, 16'b?110000000000000: mreg_b = 4'hE; 16'b1000000000000001, 16'b1000000000000010, 16'b1000000000000100, 16'b1000000000001000, 16'b1000000000010000, 16'b1000000000100000, 16'b1000000001000000, 16'b1000000010000000, 16'b1000000100000000, 16'b1000001000000000, 16'b1000010000000000, 16'b1000100000000000, 16'b1001000000000000, 16'b1010000000000000, 16'b1100000000000000: mreg_b = 4'hF; endcaseend//Mux and Latch the next reg mask value//synopsys async_set_reset "nRESET"always @(posedge nGCLK or negedge nRESET) begin if (!nRESET) next_reg_mask <= 16'h0000; else if (nWAIT) next_reg_mask <= (mul_first) ? reg_mask_b : reg_mask_c; end //Read Operand 1//For LDM/STM in 2+ cycle, addr_a = next transfer//For 1st Multiply want Rs//All others want Rnalways @(second_nlu or multiply or Rn or Rs or ldm_stm or mreg_b or mul_first) begin if (ldm_stm) addr_a = mreg_b; else if (!(second_nlu ^ multiply) | mul_first) addr_a = Rn; else addr_a = Rs; end//Read Operand 2//For LDM/STM want next transfer//For most other want Rm//For 2nd of multiply or 1st store want Rdalways @(second_nlu or Rm or Rd or mreg_a or stri or ldm or stm or cop_id or swap) begin if (ldm | stm) addr_b = mreg_a; else if (!cop_id & ((!second_nlu & !stri) | (second_nlu && swap))) addr_b = Rm; else addr_b = Rd; end //Set the Base Register//For LDM/STM comes from transfer list//For exception/branch want R14//for rest, want Rnalways @(Rn or ldm_stm or mreg_b or branch or und or swi or exception_id) begin if (ldm_stm) map_Rn = mreg_b; else if (branch | und | swi | exception_id) map_Rn = 4'hE; else map_Rn = Rn; end//Set the Dest Register//IF 1st LDM/STM, want first transfer//if 2+ LDM/STM want next transfer//if branch/exception, want PC//All others, Rdalways @(ldm or stm or mreg_a or branch or und or Rd or swi) begin if (ldm | stm) map_Rd = mreg_a; else if (branch | und | swi) map_Rd = 4'hF; else map_Rd = Rd; end //Create the 32-Bit Immediate Value used as Op2//All cases should be mutually exclusive.//For Undefined, should do this like the nRESET and modify PC directlyalways @(ir or ldrhi or strhi or Rs or Rm or swap or count or stm or ldm or und or swi) begin casex ({(und | swi), ldm,stm,ir[27:25],ldrhi,strhi,swap}) //synopsys parallel_case full_case //Undefined Instruciton 9'b1????????: imm_32 = {28'h0000000, swi, und, 2'h0}; //LDM or STM Instruction 9'b010??????, 9'b001??????: imm_32 = (count << 2); //LDRW or STRW with Immediate Offset 9'b0??010???: imm_32 = {20'h00000,ir[11:0]}; //LDRH or STRH with Immediate Offset 9'b0?????10?, 9'b0?????01?: imm_32 = {24'h000000,Rs,Rm};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -