From: Christopher Lu Date: Tue, 6 Jan 2009 06:06:00 +0000 (-0500) Subject: memory: preliminary, regfile: more read port, decode: more correct X-Git-Url: http://git.joshuawise.com/firearm.git/commitdiff_plain/b3bb2fb8d24456b2683c5bdb8b3b195d0f600a97?hp=-c memory: preliminary, regfile: more read port, decode: more correct --- b3bb2fb8d24456b2683c5bdb8b3b195d0f600a97 diff --git a/Decode.v b/Decode.v index 359bbc0..a34eb3b 100644 --- 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 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 diff --git a/RegFile.v b/RegFile.v index 95e5c71..1e94174 100644 --- 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