X-Git-Url: http://git.joshuawise.com/firearm.git/blobdiff_plain/2c523f8ab5b2d5e0d2a5e34f360d16439861171e..a9f76b88574c4e20ed91ab6704f3f74852584825:/Decode.v diff --git a/Decode.v b/Decode.v index d817d13..a989f42 100644 --- a/Decode.v +++ b/Decode.v @@ -2,26 +2,30 @@ module Decode( input clk, - input [31:0] insn, - input [31:0] inpc, - input [31:0] incpsr, - output reg [31:0] op0, - output reg [31:0] op1, - output reg [31:0] op2, - output reg carry, + input stall, + input [31:0] insn_1a, + input [31:0] pc_1a, + input [31:0] cpsr_1a, + input [31:0] spsr_1a, + output reg [31:0] op0_2a, + output reg [31:0] op1_2a, + output reg [31:0] op2_2a, + output reg carry_2a, + output reg [31:0] cpsr_2a, + output reg [31:0] spsr_2a, - output reg [3:0] read_0, - output reg [3:0] read_1, - output reg [3:0] read_2, - input [31:0] rdata_0, - input [31:0] rdata_1, - input [31:0] rdata_2 + output reg [3:0] rf__read_0_1a, + output reg [3:0] rf__read_1_1a, + output reg [3:0] rf__read_2_1a, + input [31:0] rf__rdata_0_1a, + input [31:0] rf__rdata_1_1a, + input [31:0] rf__rdata_2_1a ); wire [31:0] regs0, regs1, regs2; reg [31:0] rpc; - reg [31:0] op0_out, op1_out, op2_out; - reg carry_out; + reg [31:0] op0_1a, op1_1a, op2_1a; + reg carry_1a; /* shifter stuff */ wire [31:0] shift_oper; @@ -29,23 +33,23 @@ module Decode( wire shift_cflag_out; wire [31:0] rotate_res; - assign regs0 = (read_0 == 4'b1111) ? rpc : rdata_0; - assign regs1 = (read_1 == 4'b1111) ? rpc : rdata_1; - assign regs2 = rdata_2; /* use regs2 for things that cannot be r15 */ + assign regs0 = (rf__read_0_1a == 4'b1111) ? rpc : rf__rdata_0_1a; + assign regs1 = (rf__read_1_1a == 4'b1111) ? rpc : rf__rdata_1_1a; + assign regs2 = rf__rdata_2_1a; /* use regs2 for things that cannot be r15 */ - IREALLYHATEARMSHIFT blowme(.insn(insn), - .operand(regs1), - .reg_amt(regs2), - .cflag_in(incpsr[`CPSR_C]), - .res(shift_res), - .cflag_out(shift_cflag_out)); + IREALLYHATEARMSHIFT shift(.insn(insn_1a), + .operand(regs1), + .reg_amt(regs2), + .cflag_in(cpsr_1a[`CPSR_C]), + .res(shift_res), + .cflag_out(shift_cflag_out)); - SuckLessRotator whirr(.oper({24'b0, insn[7:0]}), - .amt(insn[11:8]), + SuckLessRotator whirr(.oper({24'b0, insn_1a[7:0]}), + .amt(insn_1a[11:8]), .res(rotate_res)); always @(*) - casez (insn) + casez (insn_1a) `DECODE_ALU_MULT, /* Multiply -- must come before ALU, because it pattern matches a specific case of ALU */ // `DECODE_ALU_MUL_LONG, /* Multiply long */ `DECODE_ALU_MRS, /* MRS (Transfer PSR to register) */ @@ -61,75 +65,76 @@ module Decode( `DECODE_BRANCH, /* Branch */ `DECODE_LDCSTC, /* Coprocessor data transfer */ `DECODE_CDP, /* Coprocessor data op */ - `DECODE_MRCMCR, /* Coprocessor register transfer */ `DECODE_SWI: /* SWI */ - rpc = inpc - 8; + rpc = pc_1a + 8; + `DECODE_MRCMCR: /* Coprocessor register transfer */ + rpc = pc_1a + 12; `DECODE_ALU: /* ALU */ - rpc = inpc - (insn[25] ? 8 : (insn[4] ? 12 : 8)); + rpc = pc_1a + (insn_1a[25] ? 8 : (insn_1a[4] ? 12 : 8)); default: /* X everything else out */ rpc = 32'hxxxxxxxx; endcase - + always @(*) begin - read_0 = 4'hx; - read_1 = 4'hx; - read_2 = 4'hx; + rf__read_0_1a = 4'hx; + rf__read_1_1a = 4'hx; + rf__read_2_1a = 4'hx; - casez (insn) + casez (insn_1a) `DECODE_ALU_MULT: /* Multiply -- must come before ALU, because it pattern matches a specific case of ALU */ begin - read_0 = insn[15:12]; /* Rn */ - read_1 = insn[3:0]; /* Rm */ - read_2 = insn[11:8]; /* Rs */ + rf__read_0_1a = insn_1a[15:12]; /* Rn */ + rf__read_1_1a = insn_1a[3:0]; /* Rm */ + rf__read_2_1a = insn_1a[11:8]; /* Rs */ end -// `DECODE_ALU_MUL_LONG: /* Multiply long */ -// read_0 = insn[11:8]; /* Rn */ -// read_1 = insn[3:0]; /* Rm */ -// read_2 = 4'b0; /* anyus */ `DECODE_ALU_MRS: /* MRS (Transfer PSR to register) */ begin end - `DECODE_ALU_MSR, /* MSR (Transfer register to PSR) */ + `DECODE_ALU_MSR: /* MSR (Transfer register to PSR) */ + rf__read_0_1a = insn_1a[3:0]; /* Rm */ `DECODE_ALU_MSR_FLAGS: /* MSR (Transfer register or immediate to PSR, flag bits only) */ - read_0 = insn[3:0]; /* Rm */ + rf__read_0_1a = insn_1a[3:0]; /* Rm */ `DECODE_ALU_SWP: /* Atomic swap */ begin - read_0 = insn[19:16]; /* Rn */ - read_1 = insn[3:0]; /* Rm */ + rf__read_0_1a = insn_1a[19:16]; /* Rn */ + rf__read_1_1a = insn_1a[3:0]; /* Rm */ end `DECODE_ALU_BX: /* Branch and exchange */ - read_0 = insn[3:0]; /* Rn */ + rf__read_0_1a = insn_1a[3:0]; /* Rn */ `DECODE_ALU_HDATA_REG: /* Halfword transfer - register offset */ begin - read_0 = insn[19:16]; - read_1 = insn[3:0]; + rf__read_0_1a = insn_1a[19:16]; + rf__read_1_1a = insn_1a[3:0]; + rf__read_2_1a = insn_1a[15:12]; end `DECODE_ALU_HDATA_IMM: /* Halfword transfer - immediate offset */ begin - read_0 = insn[19:16]; + rf__read_0_1a = insn_1a[19:16]; + rf__read_1_1a = insn_1a[15:12]; end `DECODE_ALU: /* ALU */ begin - read_0 = insn[19:16]; /* Rn */ - read_1 = insn[3:0]; /* Rm */ - read_2 = insn[11:8]; /* Rs for shift */ + rf__read_0_1a = insn_1a[19:16]; /* Rn */ + rf__read_1_1a = insn_1a[3:0]; /* Rm */ + rf__read_2_1a = insn_1a[11:8]; /* Rs for shift */ end `DECODE_LDRSTR_UNDEFINED: /* Undefined. I hate ARM */ begin end `DECODE_LDRSTR: /* Single data transfer */ begin - read_0 = insn[19:16]; /* Rn */ - read_1 = insn[3:0]; /* Rm */ + rf__read_0_1a = insn_1a[19:16]; /* Rn */ + rf__read_1_1a = insn_1a[3:0]; /* Rm */ + rf__read_2_1a = insn_1a[15:12]; end `DECODE_LDMSTM: /* Block data transfer */ - read_0 = insn[19:16]; + rf__read_0_1a = insn_1a[19:16]; `DECODE_BRANCH: /* Branch */ begin end `DECODE_LDCSTC: /* Coprocessor data transfer */ - read_0 = insn[19:16]; + rf__read_0_1a = insn_1a[19:16]; `DECODE_CDP: /* Coprocessor data op */ begin end `DECODE_MRCMCR: /* Coprocessor register transfer */ - read_0 = insn[15:12]; + rf__read_0_1a = insn_1a[15:12]; `DECODE_SWI: /* SWI */ begin end default: @@ -138,96 +143,101 @@ module Decode( end always @(*) begin - op0_out = 32'hxxxxxxxx; - op1_out = 32'hxxxxxxxx; - op2_out = 32'hxxxxxxxx; - carry_out = 1'bx; - casez (insn) - `DECODE_ALU_MULT: begin /* Multiply */ - op0_out = regs0; - op1_out = regs1; - op2_out = regs2; - end -// `DECODE_ALU_MULT_LONG: begin /* Multiply long */ -// op1_res = regs1; -// end - `DECODE_ALU_MRS: begin /* MRS (Transfer PSR to register) */ + op0_1a = 32'hxxxxxxxx; + op1_1a = 32'hxxxxxxxx; + op2_1a = 32'hxxxxxxxx; + carry_1a = 1'bx; + + casez (insn_1a) + `DECODE_ALU_MULT: /* Multiply -- must come before ALU, because it pattern matches a specific case of ALU */ + begin + op0_1a = regs0; + op1_1a = regs1; + op2_1a = regs2; end - `DECODE_ALU_MSR: begin /* MSR (Transfer register to PSR) */ - op0_out = regs0; - end - `DECODE_ALU_MSR_FLAGS: begin /* MSR (Transfer register or immediate to PSR, flag bits only) */ - if(insn[25]) begin /* the constant case */ - op0_out = rotate_res; + `DECODE_ALU_MRS: /* MRS (Transfer PSR to register) */ + begin end + `DECODE_ALU_MSR: /* MSR (Transfer register to PSR) */ + op0_1a = regs0; + `DECODE_ALU_MSR_FLAGS: /* MSR (Transfer register or immediate to PSR, flag bits only) */ + if(insn_1a[25]) begin /* the constant case */ + op0_1a = rotate_res; end else begin - op0_out = regs0; + op0_1a = regs0; end - end - `DECODE_ALU_SWP: begin /* Atomic swap */ - op0_out = regs0; - op1_out = regs1; - end - `DECODE_ALU_BX: begin /* Branch and exchange */ - op0_out = regs0; + `DECODE_ALU_SWP: /* Atomic swap */ + begin + op0_1a = regs0; + op1_1a = regs1; end - `DECODE_ALU_HDATA_REG: begin /* Halfword transfer - register offset */ - op0_out = regs0; - op1_out = regs1; + `DECODE_ALU_BX: /* Branch and exchange */ + op0_1a = regs0; + `DECODE_ALU_HDATA_REG: /* Halfword transfer - register offset */ + begin + op0_1a = regs0; + op1_1a = regs1; + op2_1a = regs2; end - `DECODE_ALU_HDATA_IMM: begin /* Halfword transfer - immediate offset */ - op0_out = regs0; - op1_out = {24'b0, insn[11:8], insn[3:0]}; + `DECODE_ALU_HDATA_IMM: /* Halfword transfer - immediate offset */ + begin + op0_1a = regs0; + op1_1a = {24'b0, insn_1a[11:8], insn_1a[3:0]}; + op2_1a = regs1; end - `DECODE_ALU: begin /* ALU */ - op0_out = regs0; - if(insn[25]) begin /* the constant case */ - carry_out = incpsr[`CPSR_C]; - op1_out = rotate_res; + `DECODE_ALU: /* ALU */ + begin + op0_1a = regs0; + if(insn_1a[25]) begin /* the constant case */ + carry_1a = cpsr_1a[`CPSR_C]; + op1_1a = rotate_res; end else begin - carry_out = shift_cflag_out; - op1_out = shift_res; + carry_1a = shift_cflag_out; + op1_1a = shift_res; end end - `DECODE_LDRSTR_UNDEFINED: begin /* Undefined. I hate ARM */ - /* eat shit */ - end - `DECODE_LDRSTR: begin /* Single data transfer */ - op0_out = regs0; - if(insn[25]) begin - op1_out = {20'b0, insn[11:0]}; - carry_out = incpsr[`CPSR_C]; + `DECODE_LDRSTR: /* Single data transfer */ + begin + op0_1a = regs0; + if(!insn_1a[25] /* immediate */) begin + op1_1a = {20'b0, insn_1a[11:0]}; + carry_1a = cpsr_1a[`CPSR_C]; end else begin - op1_out = shift_res; - carry_out = shift_cflag_out; + op1_1a = shift_res; + carry_1a = shift_cflag_out; end + op2_1a = regs2; end - `DECODE_LDMSTM: begin /* Block data transfer */ - op0_out = regs0; - op1_out = {16'b0, insn[15:0]}; - end - `DECODE_BRANCH: begin /* Branch */ - op0_out = {{6{insn[23]}}, insn[23:0], 2'b0}; - end - `DECODE_LDCSTC: begin /* Coprocessor data transfer */ - op0_out = regs0; - op1_out = {24'b0, insn[7:0]}; - end - `DECODE_CDP: begin /* Coprocessor data op */ - end - `DECODE_MRCMCR: begin /* Coprocessor register transfer */ - op0_out = regs0; + `DECODE_LDMSTM: /* Block data transfer */ + begin + op0_1a = regs0; + op1_1a = {16'b0, insn_1a[15:0]}; end - `DECODE_SWI: begin /* SWI */ + `DECODE_BRANCH: /* Branch */ + op0_1a = {{6{insn_1a[23]}}, insn_1a[23:0], 2'b0}; + `DECODE_LDCSTC: /* Coprocessor data transfer */ + begin + op0_1a = regs0; + op1_1a = {24'b0, insn_1a[7:0]}; end - default: begin end + `DECODE_CDP: /* Coprocessor data op */ + begin end + `DECODE_MRCMCR: /* Coprocessor register transfer */ + op0_1a = regs0; + `DECODE_SWI: /* SWI */ + begin end endcase end - + always @ (posedge clk) begin - op0 <= op0_out; /* Rn - always */ - op1 <= op1_out; /* 'operand 2' - Rm */ - op2 <= op2_out; /* thirdedge - Rs */ - carry <= carry_out; + if (!stall) + begin + op0_2a <= op0_1a; /* Rn - always */ + op1_2a <= op1_1a; /* 'operand 2' - Rm */ + op2_2a <= op2_1a; /* thirdedge - Rs */ + carry_2a <= carry_1a; + cpsr_2a <= cpsr_1a; + spsr_2a <= spsr_1a; + end end endmodule @@ -248,7 +258,7 @@ module IREALLYHATEARMSHIFT( assign shift_amt = insn[4] ? {|reg_amt[7:5], reg_amt[4:0]} /* reg-specified shift */ : {insn[11:7] == 5'b0, insn[11:7]}; /* immediate shift */ - SuckLessShifter biteme(.oper(operand), + SuckLessShifter barrel(.oper(operand), .carryin(cflag_in), .amt(shift_amt), .is_arith(is_arith), @@ -338,3 +348,4 @@ module SuckLessRotator( assign res = amt[0] ? {stage3[1:0], stage3[31:2]} : stage3; endmodule +