X-Git-Url: http://git.joshuawise.com/firearm.git/blobdiff_plain/e54a317f08318dc016159cd7784108ca753a494f..6d8250a2274c30477c543fa7279b9f3052afcca2:/Memory.v?ds=inline diff --git a/Memory.v b/Memory.v index 9855411..1dad548 100644 --- a/Memory.v +++ b/Memory.v @@ -121,6 +121,7 @@ module Memory( lsrh_state <= next_lsrh_state; if (do_rd_data_latch) rd_data_latch <= rd_data; + swp_oldval <= next_swp_oldval; prevaddr <= addr; end @@ -160,7 +161,10 @@ module Memory( end endcase end - `DECODE_ALU_MULT: begin end + `DECODE_ALU_MULT: begin + outstall = 1'b0; /* XXX work around for Xilinx bug */ + next_lsrh_state = lsrh_state; + end `DECODE_ALU_HDATA_REG, `DECODE_ALU_HDATA_IMM: if(!inbubble) begin case(lsrh_state) @@ -254,11 +258,11 @@ module Memory( end `LSM_MEMIO: begin outstall = 1'b1; - if(next_regs == 16'b0) begin + if(next_regs == 16'b0 && !rw_wait) begin next_lsm_state = `LSM_BASEWB; end - $display("LDMSTM: Stage 2: Writing: regs %b, next_regs %b, reg %d, wr_data %08x, addr %08x", regs, next_regs, cur_reg, wr_data, busaddr); + $display("LDMSTM: Stage 2: Writing: regs %b, next_regs %b, reg %d, wr_data %08x, addr %08x", regs, next_regs, cur_reg, st_data, busaddr); end `LSM_BASEWB: begin outstall = 1; @@ -345,7 +349,13 @@ module Memory( default: begin end endcase end - `DECODE_ALU_MULT: begin end + `DECODE_ALU_MULT: begin + next_write_reg = write_reg; /* XXX workaround for ISE 10.1 bug */ + next_write_num = write_num; + next_write_data = write_data; + next_outcpsr = lsm_state == 4'b0010 ? outcpsr : cpsr; + next_outcpsrup = cpsrup; + end `DECODE_ALU_HDATA_REG, `DECODE_ALU_HDATA_IMM: if(!inbubble) begin next_write_reg = 1'bx; @@ -402,7 +412,7 @@ module Memory( `LSM_SETUP: next_write_reg = 1'b0; `LSM_MEMIO: begin - if(insn[20]) begin + if(insn[20] /* L */) begin next_write_reg = !rw_wait; next_write_num = cur_reg; next_write_data = rd_data; @@ -465,7 +475,12 @@ module Memory( default: begin end endcase end - `DECODE_ALU_MULT: begin end + `DECODE_ALU_MULT: begin + rd_req = 1'b0; /* XXX workaround for Xilinx bug */ + wr_req = 1'b0; + offset = prev_offset; + addr = prevaddr; + end `DECODE_ALU_HDATA_REG, `DECODE_ALU_HDATA_IMM: if(!inbubble) begin addr = insn[23] ? op0 + op1 : op0 - op1; /* up/down select */ @@ -480,7 +495,6 @@ module Memory( 2'b11: /* signed half */ data_size = 3'b010; default: begin - wr_data = 32'hxxxxxxxx; data_size = 3'bxxx; end endcase @@ -500,7 +514,6 @@ module Memory( addr = insn[23] ? op0 + op1 : op0 - op1; /* up/down select */ raddr = insn[24] ? addr : op0; /* pre/post increment */ busaddr = raddr; - wr_data = insn[22] ? {24'h0, {op2[7:0]}} : op2; data_size = insn[22] ? 3'b001 : 3'b100; case (lsr_state) `LSR_MEMIO: begin @@ -572,7 +585,7 @@ module Memory( endcase end `DECODE_LDMSTM: if (!inbubble) - if (lsr_state == `LSM_MEMIO) + if (lsm_state == `LSM_MEMIO) wr_data = (cur_reg == 4'hF) ? (pc + 12) : st_data; `DECODE_LDCSTC: begin end `DECODE_CDP: begin end @@ -583,7 +596,7 @@ module Memory( /* LDM/STM register control logic. */ always @(posedge clk) - if (!rw_wait) + if (!rw_wait || lsm_state != `LSM_MEMIO) begin prev_reg <= cur_reg; regs <= next_regs; @@ -591,7 +604,7 @@ module Memory( always @(*) begin - offset = prev_offset; + st_read = 4'hx; cur_reg = prev_reg; next_regs = regs; @@ -686,7 +699,6 @@ module Memory( always @(*) begin - st_read = 4'hx; do_rd_data_latch = 0; next_outbubble = inbubble; @@ -695,6 +707,10 @@ module Memory( lsrh_rddata_s1 = 16'hxxxx; lsrh_rddata_s2 = 8'hxx; next_swp_oldval = swp_oldval; + + align_s1 = 32'hxxxxxxxx; + align_s2 = 32'hxxxxxxxx; + align_rddata = 32'hxxxxxxxx; /* XXX shit not given about endianness */ casez(insn) @@ -708,7 +724,9 @@ module Memory( default: begin end endcase end - `DECODE_ALU_MULT: begin end + `DECODE_ALU_MULT: begin + next_outbubble = inbubble; /* XXX workaround for Xilinx bug */ + end `DECODE_ALU_HDATA_REG, `DECODE_ALU_HDATA_IMM: if(!inbubble) begin next_outbubble = rw_wait;