?? arm10.v
字號:
psr_dest[0] = 3'h0; psr_valid[0]= 1'b1; end end end endtask //UMULL, UMLAL, SMULL, & SMLAL, Instructions task mull; reg [31:0] op1; //Multiplicand reg [31:0] op2; //Multiplier reg [63:0] acc; //Accumulate Value reg [31:0] temp; //used to get bits of a reg reg [31:0] tmp_psr; //copy of CPSR reg [63:0] m_res; //64-bit result reg s1, s2; //Sign Bits begin //Read the Operand Values from Rm & Rs op1 = reg_decode(map(Rs)); op2 = reg_decode(map(Rm)); acc[63:32] = reg_decode(map(Rn)); acc[31:0] = reg_decode(map(Rd)); //Set the Sign Bits s1 = op1[31] ? 1'b1 : 1'b0; s2 = op2[31] ? 1'b1 : 1'b0; //Setup the Operands for Signed Multiply if (ir[22] == 1'b1) begin op1 = op1[31] ? (~op1 + 1) : op1; op2 = op2[31] ? (~op2 + 1) : op2; end //Read the CPSR tmp_psr = CPSR; //Perform the Multiplication m_res = op1*op2; //Convert to Negative if Signed and Signs were different if ((s1 != s2) && (ir[22] == 1'b1)) m_res = ~m_res + 1; //Add on the Acc Value for UMLAL & SMLAL if (ir[21] == 1'b1) m_res = m_res + acc; inst_result[0] = m_res[31:0]; result_dest[0] = map(Rd); result_valid[0] = 1'b1; inst_result[1] = m_res[63:32]; result_dest[1] = map(Rn); result_valid[1] = 1'b1; //Set Flags if (S == 1'b1) begin if (m_res == 64'h0000000000000000) psr_result[0] = {2'b01, tmp_psr[29:0]}; else psr_result[0] = {m_res[63], 1'b0, tmp_psr[29:0]}; psr_dest[0] = 3'h0; psr_valid[0]= 1'b1; end end endtask //ALU Operations task alu; reg [31:0] op1; reg [31:0] shifted_op2; reg [31:0] alu_op2; reg [31:0] tmp_psr; reg [31:0] logic_result; reg [32:0] arith_result; reg shift_c_out; reg oflow; begin //Store temp copy of CPSR; tmp_psr = CPSR; //Assign the first Operand if ((ir[4] == 1'b1) && (ir[25] == 1'b0) && (Rn == 4'hF)) op1 = reg_decode(map(Rn)) + 4; else op1 = reg_decode(map(Rn)); //Perform the Shift if (ir[25] == 1'b1) {shift_c_out, shifted_op2} = shift({{24{1'b0}},ir[7:0]}); else {shift_c_out, shifted_op2} = shift(reg_decode(map(Rm))); //Perform the proper operation case (ir[24:21]) `AND: begin logic_result = op1 & shifted_op2; inst_result[0] = logic_result; result_dest[0] = map(Rd); result_valid[0] = 1'b1; //Set the Flags if necessary if (S == 1'b1) begin if (logic_result == 32'h00000000) psr_result[0] = {2'b01, shift_c_out, tmp_psr[28:0]}; else psr_result[0] = {logic_result[31], 1'b0, shift_c_out, tmp_psr[28:0]}; psr_dest[0] = 3'h0; psr_valid[0]= 1'b1; end end `EOR: begin logic_result = op1 ^ shifted_op2; inst_result[0] = logic_result; result_dest[0] = map(Rd); result_valid[0] = 1'b1; //Set the Flags if (S == 1'b1) begin if (logic_result == 32'h00000000) psr_result[0] = {2'b01, shift_c_out, tmp_psr[28:0]}; else psr_result[0] = {logic_result[31], 1'b0, shift_c_out, tmp_psr[28:0]}; end end `SUB: begin alu_op2 = ~(shifted_op2); arith_result = {1'b0,op1} + {1'b0,alu_op2} + 1; oflow = op1[31] ^ alu_op2[31] ^ arith_result[31] ^ arith_result[32]; inst_result[0] = arith_result[31:0]; result_dest[0] = map(Rd); result_valid[0] = 1'b1; //Set the Flags if necessary if (S == 1'b1) begin if (arith_result[31:0] == 32'h00000000) psr_result[0] = {2'b01, arith_result[32], oflow, tmp_psr[27:0]}; else psr_result[0] = {arith_result[31], 1'b0, arith_result[32], oflow, tmp_psr[27:0]}; end end `RSB: begin alu_op2 = ~op1; arith_result = {1'b0,shifted_op2} + {1'b0,alu_op2} + 1; oflow = shifted_op2[31] ^ alu_op2[31] ^ arith_result[31] ^ arith_result[32]; inst_result[0] = arith_result[31:0]; result_dest[0] = map(Rd); result_valid[0] = 1'b1; //Set the Flags if necessary if (S == 1'b1) begin if (arith_result[31:0] == 32'h00000000) psr_result[0] = {2'b01, arith_result[32], oflow, tmp_psr[27:0]}; else psr_result[0] = {arith_result[31], 1'b0, arith_result[32], oflow, tmp_psr[27:0]}; end end `ADD: begin alu_op2 = shifted_op2; arith_result = {1'b0,op1} + {1'b0,alu_op2}; oflow = op1[31] ^ alu_op2[31] ^ arith_result[31] ^ arith_result[32]; inst_result[0] = arith_result[31:0]; result_dest[0] = map(Rd); result_valid[0] = 1'b1; //Set the Flags if necessary if (S == 1'b1) begin if (arith_result[31:0] == 32'h00000000) psr_result[0] = {2'b01, arith_result[32], oflow, tmp_psr[27:0]}; else psr_result[0] = {arith_result[31], 1'b0, arith_result[32], oflow, tmp_psr[27:0]}; end end `ADC: begin alu_op2 = shifted_op2; arith_result = {1'b0,op1} + {1'b0,alu_op2} + C; oflow = op1[31] ^ alu_op2[31] ^ arith_result[31] ^ arith_result[32]; inst_result[0] = arith_result[31:0]; result_dest[0] = map(Rd); result_valid[0] = 1'b1; //Set the Flags if necessary if (S == 1'b1) begin if (arith_result[31:0] == 32'h00000000) psr_result[0] = {2'b01, arith_result[32], oflow, tmp_psr[27:0]}; else psr_result[0] = {arith_result[31], 1'b0, arith_result[32], oflow, tmp_psr[27:0]}; end end `SBC: begin alu_op2 = ~shifted_op2; arith_result = {1'b0,op1} + {1'b0,alu_op2} + C; oflow = op1[31] ^ alu_op2[31] ^ arith_result[31] ^ arith_result[32]; inst_result[0] = arith_result[31:0]; result_dest[0] = map(Rd); result_valid[0] = 1'b1; //Set the Flags if necessary if (S == 1'b1) begin if (arith_result[31:0] == 32'h00000000) psr_result[0] = {2'b01, arith_result[32], oflow, tmp_psr[27:0]}; else psr_result[0] = {arith_result[31], 1'b0, arith_result[32], oflow, tmp_psr[27:0]}; end end `RSC: begin alu_op2 = ~op1; arith_result = {1'b0,shifted_op2} + {1'b0,alu_op2} + C; oflow = shifted_op2[31] ^ alu_op2[31] ^ arith_result[31] ^ arith_result[32]; inst_result[0] = arith_result[31:0]; result_dest[0] = map(Rd); result_valid[0] = 1'b1; //Set the Flags if necessary if (S == 1'b1) begin if (arith_result[31:0] == 32'h00000000) psr_result[0] = {2'b01, arith_result[32], oflow, tmp_psr[27:0]}; else psr_result[0] = {arith_result[31], 1'b0, arith_result[32], oflow, tmp_psr[27:0]}; end end `TST: begin logic_result = op1 & shifted_op2; //Set the Flags if necessary if (S == 1'b1) begin if (logic_result == 32'h00000000) psr_result[0] = {2'b01, shift_c_out, tmp_psr[28:0]}; else psr_result[0] = {logic_result[31], 1'b0, shift_c_out, tmp_psr[28:0]}; end end `TEQ: begin logic_result = op1 ^ shifted_op2; //Set the Flags if (S == 1'b1) begin if (logic_result == 32'h00000000) psr_result[0] = {2'b01, shift_c_out, tmp_psr[28:0]}; else psr_result[0] = {logic_result[31], 1'b0, shift_c_out, tmp_psr[28:0]}; end end `CMP: begin alu_op2 = ~shifted_op2; arith_result = {1'b0,op1} + {1'b0,alu_op2} + 1; oflow = op1[31] ^ alu_op2[31] ^ arith_result[31] ^ arith_result[32]; //Set the Flags if necessary if (S == 1'b1) begin if (arith_result[31:0] == 32'h00000000) psr_result[0] = {2'b01, arith_result[32], oflow, tmp_psr[27:0]}; else psr_result[0] = {arith_result[31], 1'b0, arith_result[32], oflow, tmp_psr[27:0]}; end end `CMN: begin alu_op2 = shifted_op2; arith_result = {1'b0,op1} + {1'b0,alu_op2}; oflow = op1[31] ^ alu_op2[31] ^ arith_result[31] ^ arith_result[32]; //Set the Flags if necessary if (S == 1'b1) begin if (arith_result[31:0] == 32'h00000000) psr_result[0] = {2'b01, arith_result[32], oflow, tmp_psr[27:0]}; else psr_result[0] = {arith_result[31], 1'b0, arith_result[32], oflow, tmp_psr[27:0]}; end end `ORR: begin logic_result = op1 | shifted_op2; inst_result[0] = logic_result; result_dest[0] = map(Rd); result_valid[0] = 1'b1; //Set the Flags if (S == 1'b1) begin if (logic_result == 32'h00000000) psr_result[0] = {2'b01, shift_c_out, tmp_psr[28:0]}; else psr_result[0] = {logic_result[31], 1'b0, shift_c_out, tmp_psr[28:0]}; end end `MOV: begin logic_result = shifted_op2; inst_result[0] = logic_result; result_dest[0] = map(Rd); result_valid[0] = 1'b1; //Set the Flags if (S == 1'b1) begin if (logic_result == 32'h00000000) psr_result[0] = {2'b01, shift_c_out, tmp_psr[28:0]}; else psr_result[0] = {logic_result[31], 1'b0, shift_c_out, tmp_psr[28:0]}; end end `BIC: begin logic_result = op1 & (~(shifted_op2)); inst_result[0] = logic_result; result_dest[0] = map(Rd); result_valid[0] = 1'b1; //Set the Flags if (S == 1'b1) begin if (logic_result == 32'h00000000) psr_result[0] = {2'b01, shift_c_out, tmp_psr[28:0]}; else psr_result[0] = {logic_result[31], 1'b0, shift_c_out, tmp_psr[28:0]}; end end `MVN: begin logic_result = ~(shifted_op2); inst_result[0] = logic_result; result_dest[0] = map(Rd); result_valid[0] = 1'b1; //Set the Flags if (S == 1'b1) begin if (logic_result == 32'h00000000) psr_result[0] = {2'b01, shift_c_out, tmp_psr[28:0]}; else psr_result[0] = {logic_result[31], 1'b0, shift_c_out, tmp_psr[28:0]}; end end endcase psr_dest[0] = 3'h0; if (S == 1'b1) psr_valid[0] = 1'b1; end endtask //Coprocessor Instructions //This is just a basic interface, but does not //even come close to handling Coprocessor instructions. //Once it becomes time to include a Coprocessor, I'll //spice this up. task cop; reg keep_looping; reg first; begin keep_looping = 1'b1; first = 1'b1; //If Handshakes indicate ABSENT, //take Undefined Instruction trap if ((CHSD == 2'b10) || (CHSE == 2'b10)) undefined; else begin while (keep_looping == 1'b1) begin @(negedge GCLK) begin if (first == 1'b1) begin //WAIT if (CHSD == 2'b00) begin first = 1'b1; next_pc = PC; pc_touched = 1'b1; end //LAST else if (CHSD == 2'b11) begin first = 1'b0; keep_looping = 1'b0; end //GO else begin first = 1'b0; next_pc = PC; pc_touched = 1'b1; end end else begin //LAST if (CHSE == 2'b11) keep_looping = 1'b0; else begin next_pc = PC; pc_touched = 1'b1;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -