memory: preliminary, regfile: more read port, decode: more correct
authorChristopher Lu <lu@stop.hsd1.pa.comcast.net>
Tue, 6 Jan 2009 06:06:00 +0000 (01:06 -0500)
committerChristopher Lu <lu@stop.hsd1.pa.comcast.net>
Tue, 6 Jan 2009 06:06:00 +0000 (01:06 -0500)
Decode.v
Memory.v [new file with mode: 0644]
RegFile.v

index 359bbc0..a34eb3b 100644 (file)
--- a/Decode.v
+++ b/Decode.v
@@ -65,9 +65,9 @@ module Decode(
                `DECODE_CDP,                    /* Coprocessor data op */
                `DECODE_MRCMCR,                 /* Coprocessor register transfer */
                `DECODE_SWI:                    /* SWI */
-                       rpc = inpc - 8;
+                       rpc = inpc + 8;
                `DECODE_ALU:                    /* ALU */
-                       rpc = inpc - (insn[25] ? 8 : (insn[4] ? 12 : 8));
+                       rpc = inpc + (insn[25] ? 8 : (insn[4] ? 12 : 8));
                default:                        /* X everything else out */
                        rpc = 32'hxxxxxxxx;
                endcase
diff --git a/Memory.v b/Memory.v
new file mode 100644 (file)
index 0000000..2b4b2a4
--- /dev/null
+++ b/Memory.v
@@ -0,0 +1,125 @@
+`include "ARM_Constants.v"
+
+module Memory(
+       input clk,
+       input Nrst,
+       input [31:0] pc,
+       input [31:0] insn,
+       input [31:0] base,
+       input [31:0] offset,
+
+       /* bus interface */
+       output reg [31:0] busaddr,
+       output reg rd_req,
+       output reg wr_req,
+       input rw_wait,
+       output reg [31:0] wr_data,
+       input [31:0] rd_data,
+
+       /* regfile interface */
+       output reg [3:0] st_read,
+       input [31:0] st_data,
+
+       /* writeback to base */
+       output reg writeback,
+       output reg [3:0] regsel,
+       output reg [31:0] regdata,
+
+       /* pc stuff */
+       output reg [31:0] outpc,
+       output reg [31:0] newpc,
+
+       /* stall */
+       output outstall,
+       output reg outbubble,
+       output reg flush
+);
+
+       reg [31:0] addr, raddr;
+       reg notdone = 1'b0;
+       reg inc_next = 1'b0;
+       wire [31:0] align_s1, align_s2, align_rddata;
+       assign outstall = rw_wait | notdone;
+
+       always @(*)
+       begin
+               addr = 32'hxxxxxxxx;
+               raddr = 32'hxxxxxxxx;
+               rd_req = 1'b0;
+               wr_req = 1'b0;
+               wr_data = 32'hxxxxxxxx;
+               busaddr = 32'hxxxxxxxx;
+               outstall = 1'b0;
+               casez(insn)
+               `DECODE_LDRSTR_UNDEFINED: begin end
+               `DECODE_LDRSTR: begin
+                       addr = insn[23] ? base + offset : base - offset; /* up/down select */
+                       raddr = insn[24] ? base : addr;
+                       busaddr = {raddr[31:2], 2'b0}; /* pre/post increment */
+                       rd_req = insn[20];
+                       wr_req = ~insn[20];
+                       if(!insn[20]) begin /* store */
+                               st_read = insn[15:12];
+                               wr_data = insn[22] ? {4{st_data[7:0]}} : st_data;
+                       end
+                       else if(insn[15:12] == 4'hF)
+                               flush = 1'b1;
+               end
+               `DECODE_LDMSTM: begin
+               end
+               default: begin end
+               endcase
+       end
+
+       assign align_s1 = raddr[1] ? {rd_data[15:0], rd_data[31:16]} : rd_data;
+       assign align_s2 = raddr[0] ? {align_s1[7:0], align_s1[31:8]} : align_s1;
+       assign align_rddata = insn[22] ? {24'b0, align_s2[7:0]} : align_s2;
+
+       always @(posedge clk)
+       begin
+               outpc <= pc;
+               outbubble <= rw_wait;
+               casez(insn)
+               `DECODE_LDRSTR_UNDEFINED: begin
+                       writeback <= 1'b0;
+                       regsel <= 4'hx;
+                       regdata <= 32'hxxxxxxxx;
+                       notdone <= 1'b0;
+               end
+               `DECODE_LDRSTR: begin
+                       if(insn[20] && !inc_next) begin /* load - delegate regfile write to writeback stage */
+                               if(insn[15:12] == 4'hF) begin
+                                       newpc <= align_rddata;
+                               end
+                               else begin
+                                       writeback <= 1'b1;
+                                       regsel <= insn[15:12];
+                                       regdata <= align_rddata;
+                               end
+                               inc_next <= 1'b1;
+                       end
+                       else if(insn[21]) begin /* write back */
+                               writeback <= 1'b1;
+                               regsel <= insn[19:16];
+                               regdata <= addr;
+                               inc_next <= 1'b0;
+                       end else begin
+                               writeback <= 1'b0;
+                               inc_next <= 1'b0;
+                               regsel <= 4'hx;
+                               regdata <= 32'hxxxxxxxx;
+                       end
+                       notdone <= rw_wait & insn[20] & insn[21];
+               end
+               `DECODE_LDMSTM: begin
+               end
+               default: begin
+                       writeback <= 1'b0;
+                       regsel <= 4'hx;
+                       regdata <= 32'hxxxxxxxx;
+                       notdone <= 1'b0;
+               end
+               endcase
+       end
+
+endmodule
index 95e5c71..1e94174 100644 (file)
--- a/RegFile.v
+++ b/RegFile.v
@@ -6,6 +6,8 @@ module RegFile(
        output reg [31:0] rdata_1,
        input [3:0] read_2,
        output reg [31:0] rdata_2,
+       input [3:0] read_3,
+       output reg [31:0] rdata_3,
        output reg [31:0] spsr,
        input [3:0] write,
        input write_req,
@@ -49,6 +51,11 @@ module RegFile(
                        rdata_2 = write_data;
                else
                        rdata_2 = regfile[read_2];
+
+               if ((read_3 == write) && write_req)
+                       rdata_3 = write_data;
+               else
+                       rdata_3 = regfile[read_3];
                
                spsr = regfile[4'hF];
        end
This page took 0.029001 seconds and 4 git commands to generate.