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
+ output reg [31:0] write_data = 32'hxxxxxxxx,
+ output reg [31:0] jmppc,
+ output reg jmp,
+ output reg [31:0] outpc,
+ output reg [31:0] outinsn,
+ output reg [31:0] outop0, outop1, outop2
);
reg mult_start;
reg [31:0] next_outcpsr, next_outspsr;
reg next_write_reg;
reg [3:0] next_write_num;
+
reg [31:0] next_write_data;
-
+
Multiplier multiplier(
.clk(clk), .Nrst(Nrst),
.start(mult_start), .acc0(mult_acc0), .in0(mult_in0),
write_reg <= next_write_reg;
write_num <= next_write_num;
write_data <= next_write_data;
+ outpc <= pc;
+ outinsn <= insn;
+ outop0 <= op0;
+ outop1 <= op1;
+ outop2 <= op2;
end
end
always @(*)
begin
outstall = stall;
- next_outbubble = inbubble;
+ next_outbubble = inbubble | flush;
next_outcpsr = cpsr;
next_outspsr = spsr;
next_write_reg = 0;
next_write_num = 4'hx;
next_write_data = 32'hxxxxxxxx;
-
+
mult_start = 0;
mult_acc0 = 32'hxxxxxxxx;
mult_in0 = 32'hxxxxxxxx;
mult_in1 = 32'hxxxxxxxx;
-
+
alu_in0 = 32'hxxxxxxxx;
alu_in1 = 32'hxxxxxxxx;
alu_op = 4'hx; /* hax! */
alu_setflags = 1'bx;
-
+
+ jmp = 1'b0;
+ jmppc = 32'h00000000;
+
casez (insn)
`DECODE_ALU_MULT: /* Multiply -- must come before ALU, because it pattern matches a specific case of ALU */
begin
end
`DECODE_LDRSTR_UNDEFINED, /* Undefined. I hate ARM */
`DECODE_LDRSTR, /* Single data transfer */
- `DECODE_LDMSTM, /* Block data transfer */
- `DECODE_BRANCH, /* Branch */
+ `DECODE_LDMSTM: /* Block data transfer */
+ begin end
+ `DECODE_BRANCH:
+ begin
+ if(!inbubble && !flush) begin
+ jmppc = pc + op0 + 32'h8;
+ if(insn[24]) begin
+ next_write_reg = 1;
+ next_write_num = 4'hE; /* link register */
+ next_write_data = pc + 32'h4;
+ end
+ jmp = 1'b1;
+ end
+ end /* Branch */
`DECODE_LDCSTC, /* Coprocessor data transfer */
`DECODE_CDP, /* Coprocessor data op */
`DECODE_MRCMCR, /* Coprocessor register transfer */
output reg [31:0] cpsr_out,
output reg setres
);
- wire [31:0] res;
- wire flag_n, flag_z, flag_c, flag_v, setres;
+ reg [31:0] res;
+ reg flag_n, flag_z, flag_c, flag_v;
wire [32:0] sum, diff, rdiff;
wire sum_v, diff_v, rdiff_v;