]> Joshua Wise's Git repositories - firearm.git/blobdiff - Memory.v
Decode: Fix stupid bug in which stalls did not stall the decoder.
[firearm.git] / Memory.v
index 0a5cd998b9afe5322994db0b2ec161ef9269f1e3..eb4006f5884d3c71ccd7a5e20959a4238a2d4622 100644 (file)
--- a/Memory.v
+++ b/Memory.v
@@ -4,6 +4,8 @@ module Memory(
        input clk,
        input Nrst,
 
        input clk,
        input Nrst,
 
+       input flush,
+
        /* bus interface */
        output reg [31:0] busaddr,
        output reg rd_req,
        /* bus interface */
        output reg [31:0] busaddr,
        output reg rd_req,
@@ -11,6 +13,7 @@ module Memory(
        input rw_wait,
        output reg [31:0] wr_data,
        input [31:0] rd_data,
        input rw_wait,
        output reg [31:0] wr_data,
        input [31:0] rd_data,
+       output reg [2:0] data_size,
 
        /* regfile interface */
        output reg [3:0] st_read,
 
        /* regfile interface */
        output reg [3:0] st_read,
@@ -45,8 +48,8 @@ module Memory(
        output reg out_write_reg = 1'b0,
        output reg [3:0] out_write_num = 4'bxxxx,
        output reg [31:0] out_write_data = 32'hxxxxxxxx,
        output reg out_write_reg = 1'b0,
        output reg [3:0] out_write_num = 4'bxxxx,
        output reg [31:0] out_write_data = 32'hxxxxxxxx,
-       output reg [31:0] out_spsr = 32'hxxxxxxxx,
-       output reg [31:0] out_cpsr = 32'hxxxxxxxx
+       output reg [31:0] outspsr = 32'hxxxxxxxx,
+       output reg [31:0] outcpsr = 32'hxxxxxxxx
        );
 
        reg [31:0] addr, raddr, prev_raddr, next_regdata, next_outcpsr;
        );
 
        reg [31:0] addr, raddr, prev_raddr, next_regdata, next_outcpsr;
@@ -86,8 +89,8 @@ module Memory(
                prev_reg <= cur_reg;
                prev_offset <= offset;
                prev_raddr <= raddr;
                prev_reg <= cur_reg;
                prev_offset <= offset;
                prev_raddr <= raddr;
-               out_cpsr <= next_outcpsr;
-               out_spsr <= spsr;
+               outcpsr <= next_outcpsr;
+               outspsr <= spsr;
                swp_state <= next_swp_state;
                lsm_state <= next_lsm_state;
                lsr_state <= next_lsr_state;
                swp_state <= next_swp_state;
                lsm_state <= next_lsm_state;
                lsr_state <= next_lsr_state;
@@ -103,19 +106,21 @@ module Memory(
                wr_req = 1'b0;
                wr_data = 32'hxxxxxxxx;
                busaddr = 32'hxxxxxxxx;
                wr_req = 1'b0;
                wr_data = 32'hxxxxxxxx;
                busaddr = 32'hxxxxxxxx;
+               data_size = 3'bxxx;
                outstall = 1'b0;
                next_write_reg = write_reg;
                next_write_num = write_num;
                next_write_data = write_data;
                next_outbubble = inbubble;
                outstall = 1'b0;
                next_write_reg = write_reg;
                next_write_num = write_num;
                next_write_data = write_data;
                next_outbubble = inbubble;
-               outstall = 1'b0;
                next_regs = regs;
                cp_req = 1'b0;
                cp_rnw = 1'bx;
                cp_write = 32'hxxxxxxxx;
                offset = prev_offset;
                next_regs = regs;
                cp_req = 1'b0;
                cp_rnw = 1'bx;
                cp_write = 32'hxxxxxxxx;
                offset = prev_offset;
-               next_outcpsr = lsm_state == 3'b010 ? out_cpsr : cpsr;
+               next_outcpsr = lsm_state == 3'b010 ? outcpsr : cpsr;
                lsrh_rddata = 32'hxxxxxxxx;
                lsrh_rddata = 32'hxxxxxxxx;
+               lsrh_rddata_s1 = 16'hxxxx;
+               lsrh_rddata_s2 = 8'hxx;
                next_lsm_state = lsm_state;
                next_lsr_state = lsr_state;
                next_lsrh_state = lsrh_state;
                next_lsm_state = lsm_state;
                next_lsr_state = lsr_state;
                next_lsrh_state = lsrh_state;
@@ -124,12 +129,14 @@ module Memory(
                cur_reg = prev_reg;
 
                /* XXX shit not given about endianness */
                cur_reg = prev_reg;
 
                /* XXX shit not given about endianness */
-               /* TODO ldrh/strh */
-               casez(insn)
+               if (flush)
+                       next_outbubble = 1'b1;
+               else casez(insn)
                `DECODE_ALU_SWP: if(!inbubble) begin
                        outstall = rw_wait;
                        next_outbubble = rw_wait;
                        busaddr = {op0[31:2], 2'b0};
                `DECODE_ALU_SWP: if(!inbubble) begin
                        outstall = rw_wait;
                        next_outbubble = rw_wait;
                        busaddr = {op0[31:2], 2'b0};
+                       data_size = insn[22] ? 3'b001 : 3'b100;
                        case(swp_state)
                        2'b01: begin
                                rd_req = 1'b1;
                        case(swp_state)
                        2'b01: begin
                                rd_req = 1'b1;
@@ -141,10 +148,10 @@ module Memory(
                        end
                        2'b10: begin
                                wr_req = 1'b1;
                        end
                        2'b10: begin
                                wr_req = 1'b1;
-                               wr_data = op1;
+                               wr_data = insn[22] ? {4{op1[7:0]}} : op1;
                                next_write_reg = 1'b1;
                                next_write_num = insn[15:12];
                                next_write_reg = 1'b1;
                                next_write_num = insn[15:12];
-                               next_write_data = swp_oldval;
+                               next_write_data = insn[22] ? {24'b0, swp_oldval[7:0]} : swp_oldval;
                                if(!rw_wait)
                                        next_swp_state = 2'b01;
                        end
                                if(!rw_wait)
                                        next_swp_state = 2'b01;
                        end
@@ -163,16 +170,19 @@ module Memory(
                        2'b00: begin end /* swp */
                        2'b01: begin /* unsigned half */
                                wr_data = {2{op2[15:0]}}; /* XXX need to store halfword */
                        2'b00: begin end /* swp */
                        2'b01: begin /* unsigned half */
                                wr_data = {2{op2[15:0]}}; /* XXX need to store halfword */
+                               data_size = 3'b010;
                                lsrh_rddata = {16'b0, raddr[1] ? rd_data[31:16] : rd_data[15:0]};
                        end
                        2'b10: begin /* signed byte */
                                wr_data = {4{op2[7:0]}};
                                lsrh_rddata = {16'b0, raddr[1] ? rd_data[31:16] : rd_data[15:0]};
                        end
                        2'b10: begin /* signed byte */
                                wr_data = {4{op2[7:0]}};
+                               data_size = 3'b001;
                                lsrh_rddata_s1 = raddr[1] ? rd_data[31:16] : rd_data[15:0];
                                lsrh_rddata_s2 = raddr[0] ? lsrh_rddata_s1[15:8] : lsrh_rddata_s1[7:0];
                                lsrh_rddata = {{24{lsrh_rddata_s2[7]}}, lsrh_rddata_s2};
                        end
                        2'b11: begin /* signed half */
                                wr_data = {2{op2[15:0]}};
                                lsrh_rddata_s1 = raddr[1] ? rd_data[31:16] : rd_data[15:0];
                                lsrh_rddata_s2 = raddr[0] ? lsrh_rddata_s1[15:8] : lsrh_rddata_s1[7:0];
                                lsrh_rddata = {{24{lsrh_rddata_s2[7]}}, lsrh_rddata_s2};
                        end
                        2'b11: begin /* signed half */
                                wr_data = {2{op2[15:0]}};
+                               data_size = 3'b010;
                                lsrh_rddata = raddr[1] ? {{16{rd_data[31]}}, rd_data[31:16]} : {{16{rd_data[15]}}, rd_data[15:0]};
                        end
                        endcase
                                lsrh_rddata = raddr[1] ? {{16{rd_data[31]}}, rd_data[31:16]} : {{16{rd_data[15]}}, rd_data[15:0]};
                        end
                        endcase
@@ -214,6 +224,7 @@ module Memory(
                        /* select byte or word */
                        align_rddata = insn[22] ? {24'b0, align_s2[7:0]} : align_s2;
                        wr_data = insn[22] ? {4{op2[7:0]}} : op2; /* XXX need to actually store just a byte */
                        /* select byte or word */
                        align_rddata = insn[22] ? {24'b0, align_s2[7:0]} : align_s2;
                        wr_data = insn[22] ? {4{op2[7:0]}} : op2; /* XXX need to actually store just a byte */
+                       data_size = insn[22] ? 3'b001 : 3'b100;
                        case(lsr_state)
                        2'b01: begin
                                rd_req = insn[20];
                        case(lsr_state)
                        2'b01: begin
                                rd_req = insn[20];
@@ -242,6 +253,7 @@ module Memory(
                `DECODE_LDMSTM: if(!inbubble) begin
                        outstall = rw_wait;
                        next_outbubble = rw_wait;
                `DECODE_LDMSTM: if(!inbubble) begin
                        outstall = rw_wait;
                        next_outbubble = rw_wait;
+                       data_size = 3'b100;
                        case(lsm_state)
                        3'b001: begin
 //                             next_regs = insn[23] ? op1[15:0] : op1[0:15];
                        case(lsm_state)
                        3'b001: begin
 //                             next_regs = insn[23] ? op1[15:0] : op1[0:15];
This page took 0.02703 seconds and 4 git commands to generate.