From cb0428b6a01af21f4c98bb827405d18239a1f97f Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Mon, 5 Jan 2009 02:41:47 -0500 Subject: [PATCH] Add SPSR logic to Execute. --- ARM_Constants.v | 8 ++++++++ Decode.v | 3 +++ Execute.v | 34 +++++++++++++++++++++++++++++----- RegFile.v | 5 ++++- system.v | 12 ++++++------ 5 files changed, 50 insertions(+), 12 deletions(-) diff --git a/ARM_Constants.v b/ARM_Constants.v index 6a54819..2398e8d 100644 --- a/ARM_Constants.v +++ b/ARM_Constants.v @@ -69,3 +69,11 @@ `define DECODE_CDP 32'b????1110???????????????????0???? /* Coprocessor data op */ `define DECODE_MRCMCR 32'b????1110???????????????????1???? /* Coprocessor register transfer */ `define DECODE_SWI 32'b????1111???????????????????????? /* SWI */ + +`define MODE_USR 5'b10000 +`define MODE_FIQ 5'b10001 +`define MODE_IRQ 5'b10010 +`define MODE_SVC 5'b10011 +`define MODE_ABT 5'b10111 +`define MODE_UND 5'b11011 +`define MODE_SYS 5'b11111 diff --git a/Decode.v b/Decode.v index 6cfe08b..359bbc0 100644 --- a/Decode.v +++ b/Decode.v @@ -5,10 +5,12 @@ module Decode( input [31:0] insn, input [31:0] inpc, input [31:0] incpsr, + input [31:0] inspsr, output reg [31:0] op0, output reg [31:0] op1, output reg [31:0] op2, output reg carry, + output reg [31:0] outspsr, output reg [3:0] read_0, output reg [3:0] read_1, @@ -220,6 +222,7 @@ module Decode( op1 <= op1_out; /* 'operand 2' - Rm */ op2 <= op2_out; /* thirdedge - Rs */ carry <= carry_out; + outspsr <= inspsr; end endmodule diff --git a/Execute.v b/Execute.v index 3a21968..7c7f357 100644 --- a/Execute.v +++ b/Execute.v @@ -9,6 +9,7 @@ module Execute( input [31:0] pc, input [31:0] insn, input [31:0] cpsr, + input [31:0] spsr, input [31:0] op0, input [31:0] op1, input [31:0] op2, @@ -17,6 +18,7 @@ module Execute( output reg outstall = 0, output reg outbubble = 1, output reg [31:0] outcpsr = 0, + output reg [31:0] outspsr = 0, output reg write_reg = 1'bx, output reg [3:0] write_num = 4'bxxxx, output reg [31:0] write_data = 32'hxxxxxxxx @@ -34,7 +36,7 @@ module Execute( wire alu_setres; reg next_outbubble; - reg [31:0] next_outcpsr; + reg [31:0] next_outcpsr, next_outspsr; reg next_write_reg; reg [3:0] next_write_num; reg [31:0] next_write_data; @@ -56,6 +58,7 @@ module Execute( begin outbubble <= next_outbubble; outcpsr <= next_outcpsr; + outspsr <= next_outspsr; write_reg <= next_write_reg; write_num <= next_write_num; write_data <= next_write_data; @@ -71,6 +74,7 @@ module Execute( outstall = stall; next_outbubble = inbubble; next_outcpsr = cpsr; + next_outspsr = spsr; next_write_reg = 0; next_write_num = 4'hx; next_write_data = 32'hxxxxxxxx; @@ -104,9 +108,29 @@ module Execute( next_write_data = mult_result; end // `DECODE_ALU_MUL_LONG, /* Multiply long */ - `DECODE_ALU_MRS, /* MRS (Transfer PSR to register) */ + `DECODE_ALU_MRS: /* MRS (Transfer PSR to register) */ + begin + next_write_reg = 1; + next_write_num = insn[15:12]; + if (insn[22] /* Ps */) + next_write_data = spsr; + else + next_write_data = cpsr; + end `DECODE_ALU_MSR, /* MSR (Transfer register to PSR) */ - `DECODE_ALU_MSR_FLAGS, /* MSR (Transfer register or immediate to PSR, flag bits only) */ + `DECODE_ALU_MSR_FLAGS: /* MSR (Transfer register or immediate to PSR, flag bits only) */ + if ((cpsr[4:0] == `MODE_USR) || (insn[16] /* that random bit */ == 1'b0)) /* flags only */ + begin + if (insn[22] /* Ps */) + next_outspsr = {op0[31:29], spsr[28:0]}; + else + next_outcpsr = {op0[31:29], cpsr[28:0]}; + end else begin + if (insn[22] /* Ps */) + next_outspsr = op0; + else + next_outcpsr = op0; + end `DECODE_ALU_SWP, /* Atomic swap */ `DECODE_ALU_BX, /* Branch */ `DECODE_ALU_HDATA_REG, /* Halfword transfer - register offset */ @@ -117,7 +141,7 @@ module Execute( alu_in0 = op0; alu_in1 = op1; alu_op = insn[24:21]; - alu_setflags = insn[20] /* I */; + alu_setflags = insn[20] /* S */; if (alu_setres) begin next_write_reg = 1; @@ -125,7 +149,7 @@ module Execute( next_write_data = alu_result; end - next_outcpsr = alu_outcpsr; + next_outcpsr = ((insn[15:12] == 4'b1111) && insn[20]) ? spsr : alu_outcpsr; end `DECODE_LDRSTR_UNDEFINED, /* Undefined. I hate ARM */ `DECODE_LDRSTR, /* Single data transfer */ diff --git a/RegFile.v b/RegFile.v index a9699e9..95e5c71 100644 --- a/RegFile.v +++ b/RegFile.v @@ -6,6 +6,7 @@ module RegFile( output reg [31:0] rdata_1, input [3:0] read_2, output reg [31:0] rdata_2, + output reg [31:0] spsr, input [3:0] write, input write_req, input [31:0] write_data @@ -29,7 +30,7 @@ module RegFile( regfile[4'hC] = 32'h0000A000; regfile[4'hD] = 32'h00000A00; regfile[4'hE] = 32'h000000A0; - regfile[4'hF] = 32'h0000000A; + regfile[4'hF] = 32'h00000000; /* Start off claiming we are in user mode. */ end always @(*) @@ -48,6 +49,8 @@ module RegFile( rdata_2 = write_data; else rdata_2 = regfile[read_2]; + + spsr = regfile[4'hF]; end always @(posedge clk) diff --git a/system.v b/system.v index 685d5bd..0961c30 100644 --- a/system.v +++ b/system.v @@ -36,10 +36,10 @@ module System(input clk); wire stall_cause_issue; wire stall_cause_execute; - wire [31:0] decode_out_op0, decode_out_op1, decode_out_op2; + wire [31:0] decode_out_op0, decode_out_op1, decode_out_op2, decode_out_spsr; wire decode_out_carry; wire [3:0] regfile_read_0, regfile_read_1, regfile_read_2; - wire [31:0] regfile_rdata_0, regfile_rdata_1, regfile_rdata_2; + wire [31:0] regfile_rdata_0, regfile_rdata_1, regfile_rdata_2, regfile_spsr; wire execute_out_stall, execute_out_bubble; wire execute_out_write_reg; wire [3:0] execute_out_write_num; @@ -92,13 +92,13 @@ module System(input clk); .clk(clk), .read_0(regfile_read_0), .read_1(regfile_read_1), .read_2(regfile_read_2), .rdata_0(regfile_rdata_0), .rdata_1(regfile_rdata_1), .rdata_2(regfile_rdata_2), - .write(4'b0), .write_req(1'b0), .write_data(10 /* XXX */)); + .spsr(regfile_spsr), .write(4'b0), .write_req(1'b0), .write_data(10 /* XXX */)); Decode decode( .clk(clk), - .insn(insn_out_fetch), .inpc(pc_out_fetch), .incpsr(32'b0 /* XXX */), + .insn(insn_out_fetch), .inpc(pc_out_fetch), .incpsr(32'b0 /* XXX */), .inspsr(regfile_spsr), .op0(decode_out_op0), .op1(decode_out_op1), .op2(decode_out_op2), - .carry(decode_out_carry), + .carry(decode_out_carry), .outspsr(decode_out_spsr), .read_0(regfile_read_0), .read_1(regfile_read_1), .read_2(regfile_read_2), .rdata_0(regfile_rdata_0), .rdata_1(regfile_rdata_1), .rdata_2(regfile_rdata_2)); @@ -106,7 +106,7 @@ module System(input clk); .clk(clk), .Nrst(1'b0), .stall(1'b0 /* XXX */), .flush(1'b0 /* XXX */), .inbubble(bubble_out_issue), .pc(pc_out_issue), .insn(insn_out_issue), - .cpsr(32'b0 /* XXX */), .op0(decode_out_op0), .op1(decode_out_op1), + .cpsr(32'b0 /* XXX */), .spsr(decode_out_spsr), .op0(decode_out_op0), .op1(decode_out_op1), .op2(decode_out_op2), .carry(decode_out_carry), .outstall(stall_cause_execute), .outbubble(execute_out_bubble), .write_reg(execute_out_write_reg), .write_num(execute_out_write_num), -- 2.39.2