From 6d18bf2758e61202ba514a431bbcfca827dd7d1e Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Sat, 24 Jan 2009 00:39:59 -0500 Subject: [PATCH 01/16] Memory: Add STRB support, en manera de A. --- Memory.v | 61 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 47 insertions(+), 14 deletions(-) diff --git a/Memory.v b/Memory.v index 7ca786e..eccddb2 100644 --- a/Memory.v +++ b/Memory.v @@ -65,7 +65,7 @@ module Memory( reg [3:0] next_write_num; reg [31:0] next_write_data; - reg [2:0] lsr_state = 3'b001, next_lsr_state; + reg [3:0] lsr_state = 4'b0001, next_lsr_state; reg [31:0] align_s1, align_s2, align_rddata; reg [2:0] lsrh_state = 3'b001, next_lsrh_state; @@ -79,6 +79,9 @@ module Memory( reg [31:0] swp_oldval, next_swp_oldval; reg [1:0] swp_state = 2'b01, next_swp_state; + + reg do_rd_data_latch; + reg [31:0] rd_data_latch = 32'hxxxxxxxx; always @(posedge clk) begin @@ -100,6 +103,8 @@ module Memory( lsm_state <= next_lsm_state; lsr_state <= next_lsr_state; lsrh_state <= next_lsrh_state; + if (do_rd_data_latch) + rd_data_latch <= rd_data; prevaddr <= addr; end @@ -120,6 +125,7 @@ module Memory( busaddr = 32'hxxxxxxxx; data_size = 3'bxxx; outstall = 1'b0; + do_rd_data_latch = 0; next_write_reg = write_reg; next_write_num = write_num; next_write_data = write_data; @@ -248,42 +254,69 @@ module Memory( align_s2 = raddr[0] ? {align_s1[7:0], align_s1[31:8]} : align_s1; /* 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 */ + wr_data = insn[22] ? {24'h0, {op2[7:0]}} : op2; data_size = insn[22] ? 3'b001 : 3'b100; case(lsr_state) - 3'b001: begin - rd_req = insn[20] /* L */; - wr_req = ~insn[20] /* L */; + 4'b0001: begin + rd_req = insn[20] /* L */ || insn[22] /* B */; + wr_req = !insn[20] /* L */ && !insn[22]/* B */; next_write_reg = insn[20] /* L */; next_write_num = insn[15:12]; if(insn[20] /* L */) begin - next_write_data = align_rddata; + next_write_data = insn[22] /* B */ ? {24'h0, align_rddata[7:0]} : align_rddata; end - if(insn[21] /* W */ | !insn[24] /* P */) begin + if (insn[22] /* B */ && !insn[20] /* L */) begin + do_rd_data_latch = 1; + outstall = 1'b1; + if (!rw_wait) + next_lsr_state = 4'b0010; /* XXX: One-hot, my ass. */ + end else if(insn[21] /* W */ | !insn[24] /* P */) begin outstall = 1'b1; if(!rw_wait) - next_lsr_state = 3'b010; + next_lsr_state = 4'b0100; end $display("LDRSTR: rd_req %d, wr_req %d, raddr %08x, wait %d", rd_req, wr_req, raddr, rw_wait); end - 3'b010: begin + 4'b0010: begin + $display("LDRSTR: Handling STRB"); outstall = 1; + rd_req = 0; + wr_req = 1; + next_write_reg = 0; + case (busaddr[1:0]) + 2'b00: wr_data = {rd_data_latch[31:8], op2[7:0]}; + 2'b01: wr_data = {rd_data_latch[31:16], op2[7:0], rd_data_latch[7:0]}; + 2'b10: wr_data = {rd_data_latch[31:24], op2[7:0], rd_data_latch[15:0]}; + 2'b11: wr_data = {op2[7:0], rd_data_latch[23:0]}; + endcase + if(insn[21] /* W */ | !insn[24] /* P */) begin + if(!rw_wait) + next_lsr_state = 4'b0100; + end else if (!rw_wait) + next_lsr_state = 4'b1000; + end + 4'b0100: begin + outstall = 1; + rd_req = 0; + wr_req= 0; next_outbubble = 0; next_write_reg = 1'b1; next_write_num = insn[19:16]; next_write_data = addr; - next_lsr_state = 3'b100; + next_lsr_state = 4'b1000; end - 3'b100: begin + 4'b1000: begin + rd_req = 0; + wr_req= 0; outstall = 0; - next_lsr_state = 3'b001; + next_lsr_state = 4'b0001; end default: begin end endcase - if ((lsr_state == 3'b001) && flush) begin /* Reject it. */ + if ((lsr_state == 4'b0001) && flush) begin /* Reject it. */ outstall = 1'b0; - next_lsr_state = 3'b001; + next_lsr_state = 4'b0001; end end /* XXX ldm/stm incorrect in that stupid case where one of the listed regs is the base reg */ -- 2.43.0 From 7282e8f84e4f5aecab6e57c2086785bbd6d48748 Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Sat, 24 Jan 2009 00:40:32 -0500 Subject: [PATCH 02/16] Terminal: Add support for reading characters. --- Terminal.v | 11 +++++++++++ testbench.cpp | 47 ++++++++++++++++++++++++++++++++++++----------- 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/Terminal.v b/Terminal.v index 89b19d5..dd041d0 100644 --- a/Terminal.v +++ b/Terminal.v @@ -12,6 +12,8 @@ module Terminal( /* Terminal pretends to be cp5. */ reg towrite = 0; reg [7:0] data = 0; + reg [8:0] indata = 0; /* High bit is if data is present. */ + reg didread = 0; always @(*) begin @@ -19,16 +21,25 @@ module Terminal( data = 8'hxx; cp_ack = 0; cp_busy = 0; + cp_read = 0; + didread = 0; if (cp_req && (cp_rnw == 0) && (cp_insn[27:24] == 4'b1110) && (cp_insn[19:16] == 4'b0000) && (cp_insn[11:8] == 4'h5)) begin towrite = 1; data = cp_write[7:0]; cp_ack = 1; + end else if (cp_req && (cp_rnw == 1) && (cp_insn[27:24] == 4'b1110) && (cp_insn[19:16] == 4'b0001) && (cp_insn[11:8] == 4'h5)) + begin + cp_read = {23'h0, indata[8:0]}; + cp_ack = 1; + didread = cp_insn[7:5] == 1; end end `ifdef verilator always @(posedge clk) if (towrite) $c("{extern void term_output(unsigned char d); term_output(",data,");}"); + else if (didread || !indata[8]) + indata = $c("({extern unsigned int term_input(); term_input();})"); `endif endmodule diff --git a/testbench.cpp b/testbench.cpp index 53be841..e89de38 100644 --- a/testbench.cpp +++ b/testbench.cpp @@ -3,26 +3,51 @@ #define _XOPEN_SOURCE #include #include +#include Vsystem *top; +int ptyfd = -1; + +void openpty() +{ + int fd = posix_openpt(O_RDWR); + char b[128]; + struct termios kbdios; + + grantpt(fd); + fcntl(fd, F_SETFD, 0); /* clear close-on-exec */ + tcgetattr(fd, &kbdios); + kbdios.c_lflag &= ~(ECHO|ECHONL|ICANON|ISIG|IEXTEN); + tcsetattr(fd, TCSANOW, &kbdios); + sprintf(b, "rxvt -pty-fd %d -bg black -fg white -title \"Output terminal\" &", fd); + system(b); + unlockpt(fd); + ptyfd = open(ptsname(fd), O_RDWR | O_NONBLOCK); + close(fd); +} + +unsigned int term_input() +{ + int rv; + unsigned char c; + if (ptyfd == -1) + openpty(); + rv = read(ptyfd, &c, 1); + if (rv < 0) + return 0; + return 0x100 | c; +} + void term_output(unsigned char d) { int fd = posix_openpt(O_RDWR); static int fd2 = -1; char b[128]; - if (fd2 == -1) - { - grantpt(fd); - fcntl(fd, F_SETFD, 0); /* clear close-on-exec */ - sprintf(b, "rxvt -pty-fd %d -bg black -fg white -title \"Output terminal\" &", fd); - system(b); - unlockpt(fd); - fd2 = open(ptsname(fd), O_RDWR); - close(fd); - } - write(fd2, &d, 1); + if (ptyfd == -1) + openpty(); + write(ptyfd, &d, 1); } unsigned int main_time = 0; -- 2.43.0 From fa1c06764950e6c965ed8ce1dcf180ae1ba2df1a Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Sat, 24 Jan 2009 00:45:12 -0500 Subject: [PATCH 03/16] tests/miniblarg: Make the ROM easier to read. --- tests/miniblarg.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tests/miniblarg.c b/tests/miniblarg.c index 8fdff0f..e32989c 100644 --- a/tests/miniblarg.c +++ b/tests/miniblarg.c @@ -13,7 +13,24 @@ int abort() int *ROM() { static int a[] = { - 3632, 9, 3584, 57, 3600, 16384, 3616, 65535, 11792, 20018, 19970, 24114, 592, 8, 3584, 10, 11792, 65535}; + 0x0E30, /* 0 */ + 0x0009, /* 1 */ + 0x0E00, /* 2 */ + 0x0039, /* 3 */ + 0x0E10, /* 4 */ + 0x4000, /* 5 */ + 0x0E20, /* 6 */ + 0xFFFF, /* 7 */ + 0x2E10, /* 8 */ + 0x4E32, /* 9 */ + 0x4E02, /* A */ + 0x5E32, /* B */ + 0x0250, /* C */ + 0x0008, /* D */ + 0x0E00, /* E */ + 0x000A, /* F */ + 0x2E10, /* 10 */ + 0xFFFF}; /* 11 */ return a; } -- 2.43.0 From 1783621cc5b0d6411aa33cf9961b29f8e440e605 Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Sat, 24 Jan 2009 00:53:37 -0500 Subject: [PATCH 04/16] Add a .gitattributes file to force hex files to be binary-like. --- .gitattributes | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..c8120ab --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.hex -crlf -diff -merge \ No newline at end of file -- 2.43.0 From 85de10c4daf4c84d590f8c649f746ef5625965f6 Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Sat, 24 Jan 2009 00:54:01 -0500 Subject: [PATCH 05/16] tests/*.hex: Update hex files. --- ram.hex | 2 +- tests/u-boot.hex | Bin 152001 -> 152073 bytes 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/ram.hex b/ram.hex index 5d115b1..96b3cdf 120000 --- a/ram.hex +++ b/ram.hex @@ -1 +1 @@ -tests/ram.hex \ No newline at end of file +tests/u-boot.hex \ No newline at end of file diff --git a/tests/u-boot.hex b/tests/u-boot.hex index 17c2466fd8a21091159d6d0a46b7a331772e0224..70038557ca555e24f0c86d4ee1e540388c6b6ca1 100644 GIT binary patch delta 7546 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 BDXIVf delta 7509 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 Date: Sat, 24 Jan 2009 00:56:31 -0500 Subject: [PATCH 06/16] Add a BigBlockRAM that's 8MB (and obviously not very synthesizable). Make system use it on verilator. --- BigBlockRAM.v | 41 +++++++++++++++++++++++++++++++++++++++++ system.v | 7 ++++++- 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 BigBlockRAM.v diff --git a/BigBlockRAM.v b/BigBlockRAM.v new file mode 100644 index 0000000..b8ccbff --- /dev/null +++ b/BigBlockRAM.v @@ -0,0 +1,41 @@ +module BigBlockRAM( + input clk, + input [31:0] bus_addr, + output wire [31:0] bus_rdata, + input [31:0] bus_wdata, + input bus_rd, + input bus_wr, + output wire bus_ready + ); + + /* This module is mapped in physical memory from 0x00000000 to + * 0x00800000. rdata and ready must be driven to zero if the + * address is not within the range of this module. + */ + wire decode = bus_addr[31:23] == 9'b0; + wire [22:0] ramaddr = {bus_addr[22:2], 2'b0}; /* mask off lower two bits + * for word alignment */ + + reg [31:0] data [((8*1024*1024) / 4 - 1):0]; + + reg [31:0] temprdata = 0; + reg [22:0] lastread = 23'h7FFFFFFF; + assign bus_rdata = (bus_rd && decode) ? temprdata : 32'h0; + + assign bus_ready = decode && + (bus_wr || (bus_rd && (lastread == ramaddr))); + + initial + $readmemh("ram.hex", data); + + always @(posedge clk) + begin + if (bus_wr && decode) + data[ramaddr[22:2]] = bus_wdata; + + /* This is not allowed to be conditional -- stupid Xilinx + * blockram. */ + temprdata <= data[ramaddr[22:2]]; + lastread <= ramaddr; + end +endmodule diff --git a/system.v b/system.v index 1741203..07adfd8 100644 --- a/system.v +++ b/system.v @@ -127,7 +127,12 @@ module System(input clk); .bus_wdata(bus_wdata_dcache), .bus_rd(bus_rd_dcache), .bus_wr(bus_wr_dcache), .bus_ready(bus_ready)); - BlockRAM blockram( +`ifdef verilator + BigBlockRAM +`else + BlockRAM +`endif + blockram( .clk(clk), .bus_addr(bus_addr), .bus_rdata(bus_rdata_blockram), .bus_wdata(bus_wdata), .bus_rd(bus_rd), .bus_wr(bus_wr), -- 2.43.0 From 74b05f6e1ac2a7e14772c4bc2b8700208797f1ed Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Sat, 24 Jan 2009 03:13:53 -0500 Subject: [PATCH 07/16] Decode: De-UNOPTFLAT it. --- Decode.v | 128 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 65 insertions(+), 63 deletions(-) diff --git a/Decode.v b/Decode.v index 2c22746..3eecd55 100644 --- a/Decode.v +++ b/Decode.v @@ -80,6 +80,69 @@ module Decode( read_1 = 4'hx; read_2 = 4'hx; + casez (insn) + `DECODE_ALU_MULT: /* Multiply -- must come before ALU, because it pattern matches a specific case of ALU */ + begin + read_0 = insn[15:12]; /* Rn */ + read_1 = insn[3:0]; /* Rm */ + read_2 = insn[11:8]; /* Rs */ + end + `DECODE_ALU_MRS: /* MRS (Transfer PSR to register) */ + begin end + `DECODE_ALU_MSR: /* MSR (Transfer register to PSR) */ + read_0 = insn[3:0]; /* Rm */ + `DECODE_ALU_MSR_FLAGS: /* MSR (Transfer register or immediate to PSR, flag bits only) */ + read_0 = insn[3:0]; /* Rm */ + `DECODE_ALU_SWP: /* Atomic swap */ + begin + read_0 = insn[19:16]; /* Rn */ + read_1 = insn[3:0]; /* Rm */ + end + `DECODE_ALU_BX: /* Branch and exchange */ + read_0 = insn[3:0]; /* Rn */ + `DECODE_ALU_HDATA_REG: /* Halfword transfer - register offset */ + begin + read_0 = insn[19:16]; + read_1 = insn[3:0]; + read_2 = insn[15:12]; + end + `DECODE_ALU_HDATA_IMM: /* Halfword transfer - immediate offset */ + begin + read_0 = insn[19:16]; + read_1 = insn[15:12]; + end + `DECODE_ALU: /* ALU */ + begin + read_0 = insn[19:16]; /* Rn */ + read_1 = insn[3:0]; /* Rm */ + read_2 = insn[11:8]; /* Rs for shift */ + end + `DECODE_LDRSTR_UNDEFINED: /* Undefined. I hate ARM */ + begin end + `DECODE_LDRSTR: /* Single data transfer */ + begin + read_0 = insn[19:16]; /* Rn */ + read_1 = insn[3:0]; /* Rm */ + read_2 = insn[15:12]; + end + `DECODE_LDMSTM: /* Block data transfer */ + read_0 = insn[19:16]; + `DECODE_BRANCH: /* Branch */ + begin end + `DECODE_LDCSTC: /* Coprocessor data transfer */ + read_0 = insn[19:16]; + `DECODE_CDP: /* Coprocessor data op */ + begin end + `DECODE_MRCMCR: /* Coprocessor register transfer */ + read_0 = insn[15:12]; + `DECODE_SWI: /* SWI */ + begin end + default: + $display("Undecoded instruction"); + endcase + end + + always @(*) begin op0_out = 32'hxxxxxxxx; op1_out = 32'hxxxxxxxx; op2_out = 32'hxxxxxxxx; @@ -88,79 +151,41 @@ module Decode( casez (insn) `DECODE_ALU_MULT: /* Multiply -- must come before ALU, because it pattern matches a specific case of ALU */ begin - read_0 = insn[15:12]; /* Rn */ - read_1 = insn[3:0]; /* Rm */ - read_2 = insn[11:8]; /* Rs */ - op0_out = regs0; op1_out = regs1; op2_out = regs2; end -// `DECODE_ALU_MUL_LONG: /* Multiply long */ -// begin -// read_0 = insn[11:8]; /* Rn */ -// read_1 = insn[3:0]; /* Rm */ -// read_2 = 4'b0; /* anyus */ -// -// op1_res = regs1; -// end `DECODE_ALU_MRS: /* MRS (Transfer PSR to register) */ begin end `DECODE_ALU_MSR: /* MSR (Transfer register to PSR) */ - begin - read_0 = insn[3:0]; /* Rm */ - op0_out = regs0; - end `DECODE_ALU_MSR_FLAGS: /* MSR (Transfer register or immediate to PSR, flag bits only) */ - begin - read_0 = insn[3:0]; /* Rm */ - if(insn[25]) begin /* the constant case */ op0_out = rotate_res; end else begin op0_out = regs0; end - end `DECODE_ALU_SWP: /* Atomic swap */ begin - read_0 = insn[19:16]; /* Rn */ - read_1 = insn[3:0]; /* Rm */ - op0_out = regs0; op1_out = regs1; end `DECODE_ALU_BX: /* Branch and exchange */ - begin - read_0 = insn[3:0]; /* Rn */ - op0_out = regs0; - end `DECODE_ALU_HDATA_REG: /* Halfword transfer - register offset */ begin - read_0 = insn[19:16]; - read_1 = insn[3:0]; - read_2 = insn[15:12]; - op0_out = regs0; op1_out = regs1; op2_out = regs2; end `DECODE_ALU_HDATA_IMM: /* Halfword transfer - immediate offset */ begin - read_0 = insn[19:16]; - read_1 = insn[15:12]; - op0_out = regs0; op1_out = {24'b0, insn[11:8], insn[3:0]}; op2_out = regs1; end `DECODE_ALU: /* ALU */ begin - read_0 = insn[19:16]; /* Rn */ - read_1 = insn[3:0]; /* Rm */ - read_2 = insn[11:8]; /* Rs for shift */ - op0_out = regs0; if(insn[25]) begin /* the constant case */ carry_out = incpsr[`CPSR_C]; @@ -170,16 +195,8 @@ module Decode( op1_out = shift_res; end end - `DECODE_LDRSTR_UNDEFINED: /* Undefined. I hate ARM */ - begin - /* eat shit */ - end `DECODE_LDRSTR: /* Single data transfer */ begin - read_0 = insn[19:16]; /* Rn */ - read_1 = insn[3:0]; /* Rm */ - read_2 = insn[15:12]; - op0_out = regs0; if(!insn[25] /* immediate */) begin op1_out = {20'b0, insn[11:0]}; @@ -192,39 +209,24 @@ module Decode( end `DECODE_LDMSTM: /* Block data transfer */ begin - read_0 = insn[19:16]; - op0_out = regs0; op1_out = {16'b0, insn[15:0]}; end `DECODE_BRANCH: /* Branch */ - begin op0_out = {{6{insn[23]}}, insn[23:0], 2'b0}; - end `DECODE_LDCSTC: /* Coprocessor data transfer */ begin - read_0 = insn[19:16]; - op0_out = regs0; op1_out = {24'b0, insn[7:0]}; end `DECODE_CDP: /* Coprocessor data op */ - begin - end + begin end `DECODE_MRCMCR: /* Coprocessor register transfer */ - begin - read_0 = insn[15:12]; - op0_out = regs0; - end `DECODE_SWI: /* SWI */ - begin - end - default: - $display("Undecoded instruction"); + begin end endcase end - always @ (posedge clk) begin if (!stall) -- 2.43.0 From 3ccca00960e338365e7ce4ce57af1ec019117212 Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Sat, 24 Jan 2009 03:44:25 -0500 Subject: [PATCH 08/16] Execute: Split things out into their own always blocks there, too. --- Execute.v | 124 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 83 insertions(+), 41 deletions(-) diff --git a/Execute.v b/Execute.v index ac446aa..c1049ba 100644 --- a/Execute.v +++ b/Execute.v @@ -89,51 +89,45 @@ module Execute( reg prevstall = 0; always @(posedge clk) prevstall <= outstall; - + always @(*) begin outstall = stall; - next_outbubble = inbubble | flush | delayedflush; + + casez (insn) + `DECODE_ALU_MULT: /* Multiply -- must come before ALU, because it pattern matches a specific case of ALU */ + outstall = outstall | ((!prevstall | !mult_done) && !inbubble); + endcase + end + + /* ALU inputs */ + always @(*) + begin + alu_in0 = op0; + alu_in1 = op1; + alu_op = insn[24:21]; + alu_setflags = insn[20] /* S */; + end + + /* Register outputs */ + always @(*) + begin next_outcpsr = cpsr; next_outspsr = spsr; next_outcpsrup = 0; 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) + + casez(insn) `DECODE_ALU_MULT: /* Multiply -- must come before ALU, because it pattern matches a specific case of ALU */ begin - if (!prevstall && !inbubble) - begin - mult_start = 1; - mult_acc0 = insn[21] /* A */ ? op0 /* Rn */ : 32'h0; - mult_in0 = op1 /* Rm */; - mult_in1 = op2 /* Rs */; - $display("New MUL instruction"); - end - outstall = outstall | ((!prevstall | !mult_done) && !inbubble); - next_outbubble = next_outbubble | !mult_done | !prevstall; next_outcpsr = insn[20] /* S */ ? {mult_result[31] /* N */, mult_result == 0 /* Z */, 1'b0 /* C */, cpsr[28] /* V */, cpsr[27:0]} : cpsr; next_outcpsrup = insn[20] /* S */; next_write_reg = 1; next_write_num = insn[19:16] /* Rd -- why the fuck isn't this the same place as ALU */; next_write_data = mult_result; end -// `DECODE_ALU_MUL_LONG, /* Multiply long */ `DECODE_ALU_MRS: /* MRS (Transfer PSR to register) */ begin next_write_reg = 1; @@ -142,7 +136,6 @@ module Execute( next_write_data = spsr; else next_write_data = cpsr; - next_outcpsrup = 1; end `DECODE_ALU_MSR, /* MSR (Transfer register to PSR) */ `DECODE_ALU_MSR_FLAGS: /* MSR (Transfer register or immediate to PSR, flag bits only) */ @@ -168,33 +161,82 @@ module Execute( begin end `DECODE_ALU: /* ALU */ begin - alu_in0 = op0; - alu_in1 = op1; - alu_op = insn[24:21]; - alu_setflags = insn[20] /* S */; - if (alu_setres) begin next_write_reg = 1; next_write_num = insn[15:12] /* Rd */; next_write_data = alu_result; end - next_outcpsr = ((insn[15:12] == 4'b1111) && insn[20]) ? spsr : alu_outcpsr; - next_outcpsrup = insn[20] /* S */; + if (insn[20] /* S */) begin + next_outcpsrup = 1; + next_outcpsr = ((insn[15:12] == 4'b1111) && insn[20]) ? spsr : alu_outcpsr; + end end `DECODE_LDRSTR_UNDEFINED, /* Undefined. I hate ARM */ `DECODE_LDRSTR, /* Single data transfer */ `DECODE_LDMSTM: /* Block data transfer */ begin end + `DECODE_BRANCH: /* Branch */ + begin + if(insn[24] /* L */) begin + next_write_reg = 1; + next_write_num = 4'hE; /* link register */ + next_write_data = pc + 32'h4; + end + end + endcase + end + + /* Multiplier inputs */ + always @(*) + begin + mult_start = 0; + mult_acc0 = 32'hxxxxxxxx; + mult_in0 = 32'hxxxxxxxx; + mult_in1 = 32'hxxxxxxxx; + + casez(insn) + `DECODE_ALU_MULT: + begin + if (!prevstall /* i.e., this is a new one */ && !inbubble /* i.e., this is a real one */) + begin + mult_start = 1; + mult_acc0 = insn[21] /* A */ ? op0 /* Rn */ : 32'h0; + mult_in0 = op1 /* Rm */; + mult_in1 = op2 /* Rs */; + $display("New MUL instruction"); + end + end + endcase + end + + /* Miscellaneous cleanup. */ + always @(*) + begin + next_outbubble = inbubble | flush | delayedflush; + + 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 */ + next_outbubble = next_outbubble | !mult_done | !prevstall; + `DECODE_ALU_MRS, /* MRS (Transfer PSR to register) */ + `DECODE_ALU_MSR, /* MSR (Transfer register to PSR) */ + `DECODE_ALU_MSR_FLAGS, /* MSR (Transfer register or immediate to PSR, flag bits only) */ + `DECODE_ALU_SWP, /* Atomic swap */ + `DECODE_ALU_BX, /* Branch */ + `DECODE_ALU_HDATA_REG, /* Halfword transfer - register offset */ + `DECODE_ALU_HDATA_IMM, /* Halfword transfer - immediate offset */ + `DECODE_ALU, /* ALU */ + `DECODE_LDRSTR_UNDEFINED, /* Undefined. I hate ARM */ + `DECODE_LDRSTR, /* Single data transfer */ + `DECODE_LDMSTM: /* Block data transfer */ + begin end `DECODE_BRANCH: begin if(!inbubble && !flush && !delayedflush && !outstall /* Let someone else take precedence. */) 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 */ -- 2.43.0 From 8b09558c6aa1ac41a28e9a16d5764df5af5704ee Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Sat, 24 Jan 2009 03:46:00 -0500 Subject: [PATCH 09/16] BigBlockRAM: Remove excess F. --- BigBlockRAM.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BigBlockRAM.v b/BigBlockRAM.v index b8ccbff..7e6ea99 100644 --- a/BigBlockRAM.v +++ b/BigBlockRAM.v @@ -19,7 +19,7 @@ module BigBlockRAM( reg [31:0] data [((8*1024*1024) / 4 - 1):0]; reg [31:0] temprdata = 0; - reg [22:0] lastread = 23'h7FFFFFFF; + reg [22:0] lastread = 23'h7FFFFF; assign bus_rdata = (bus_rd && decode) ? temprdata : 32'h0; assign bus_ready = decode && -- 2.43.0 From ac760abbb074404374f0b376981d5b1c695ac9b3 Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Sat, 24 Jan 2009 03:56:01 -0500 Subject: [PATCH 10/16] DCache, ICache: Move curdata out to its own wire for synthesis. Fix up a blocking assign that should be a nonblocking assign. --- DCache.v | 5 +++-- ICache.v | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/DCache.v b/DCache.v index ccaa6b1..f4dff5a 100644 --- a/DCache.v +++ b/DCache.v @@ -48,9 +48,10 @@ module DCache( wire cache_hit = cache_valid[idx] && (cache_tags[idx] == tag); + wire [31:0] curdata = cache_data[idx][didx_word]; always @(*) begin rw_wait = (rd_req && !cache_hit) || (wr_req && (!bus_ack || !bus_ready)); - rd_data = cache_data[idx][didx_word]; + rd_data = curdata; if (!rw_wait && rd_req) $display("DCACHE: READ COMPLETE: Addr %08x, data %08x", addr, rd_data); end @@ -90,6 +91,6 @@ module DCache( cache_valid[idx] <= 0; end end else if (wr_req && cache_hit) - cache_data[idx][addr[5:2]] = wr_data; + cache_data[idx][addr[5:2]] <= wr_data; end endmodule diff --git a/ICache.v b/ICache.v index d9fbf04..e6754b7 100644 --- a/ICache.v +++ b/ICache.v @@ -48,10 +48,11 @@ module ICache( reg [31:0] prev_rd_addr = 32'hFFFFFFFF; wire cache_hit = cache_valid[rd_idx] && (cache_tags[rd_idx] == rd_tag); - - always @(*) begin /* XXX does this work nowadays? */ + + wire [31:0] curdata = cache_data[rd_idx][rd_didx_word]; + always @(*) begin rd_wait = rd_req && !cache_hit; - rd_data = cache_data[rd_idx][rd_didx_word]; + rd_data = curdata; end reg [3:0] cache_fill_pos = 0; -- 2.43.0 From f5f16509c3105f1dc274f61c66317f3926463695 Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Sat, 24 Jan 2009 04:18:39 -0500 Subject: [PATCH 11/16] RegFile: Move to assigns, since XST can't always @(regfile). --- RegFile.v | 39 ++++++++++----------------------------- 1 file changed, 10 insertions(+), 29 deletions(-) diff --git a/RegFile.v b/RegFile.v index 730a620..c0e5abd 100644 --- a/RegFile.v +++ b/RegFile.v @@ -1,14 +1,14 @@ module RegFile( input clk, input [3:0] read_0, - output reg [31:0] rdata_0, + output wire [31:0] rdata_0, input [3:0] read_1, - output reg [31:0] rdata_1, + output wire [31:0] rdata_1, input [3:0] read_2, - output reg [31:0] rdata_2, + output wire [31:0] rdata_2, input [3:0] read_3, - output reg [31:0] rdata_3, - output reg [31:0] spsr, + output wire [31:0] rdata_3, + output wire [31:0] spsr, input write, input [3:0] write_reg, input [31:0] write_data @@ -35,30 +35,11 @@ module RegFile( regfile[4'hF] = 32'h00000000; /* Start off claiming we are in user mode. */ end - always @(*) - begin - if ((read_0 == write_reg) && write) - rdata_0 = write_data; - else - rdata_0 = regfile[read_0]; - - if ((read_1 == write_reg) && write) - rdata_1 = write_data; - else - rdata_1 = regfile[read_1]; - - if ((read_2 == write_reg) && write) - rdata_2 = write_data; - else - rdata_2 = regfile[read_2]; - - if ((read_3 == write_reg) && write) - rdata_3 = write_data; - else - rdata_3 = regfile[read_3]; - - spsr = regfile[4'hF]; - end + assign rdata_0 = ((read_0 == write_reg) && write) ? write_data : regfile[read_0]; + assign rdata_1 = ((read_1 == write_reg) && write) ? write_data : regfile[read_1]; + assign rdata_2 = ((read_2 == write_reg) && write) ? write_data : regfile[read_2]; + assign rdata_3 = ((read_3 == write_reg) && write) ? write_data : regfile[read_3]; + assign spsr = regfile[4'hF]; always @(posedge clk) if (write) -- 2.43.0 From dfddccfb552a24c60589696269a5325ec267c46d Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Sat, 24 Jan 2009 04:18:58 -0500 Subject: [PATCH 12/16] Issue: Use wires, since again XST can't always @(cpsr_inflight). --- Issue.v | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/Issue.v b/Issue.v index 792fdbd..153f25f 100644 --- a/Issue.v +++ b/Issue.v @@ -12,7 +12,7 @@ module Issue( input [31:0] inpc, input [31:0] cpsr, - output reg outstall = 0, /* stage outputs */ + output wire outstall, /* stage outputs */ output reg outbubble = 1, output reg [31:0] outpc = 0, output reg [31:0] outinsn = 0 @@ -265,10 +265,6 @@ module Issue( reg cpsr_inflight [1:0]; reg [15:0] regs_inflight [1:0]; - reg waiting_cpsr; - reg waiting_regs; - wire waiting = waiting_cpsr | waiting_regs; - initial begin cpsr_inflight[0] = 0; @@ -276,14 +272,11 @@ module Issue( regs_inflight[0] = 0; regs_inflight[1] = 0; end - - always @(*) - begin - waiting_cpsr = use_cpsr & (cpsr_inflight[0] | cpsr_inflight[1]); - waiting_regs = |(use_regs & (regs_inflight[0] | regs_inflight[1])); - - outstall = (waiting && !inbubble && !flush) || stall; /* Happens in an always @*, because it is an exception. */ - end + + wire waiting_cpsr = use_cpsr & (cpsr_inflight[0] | cpsr_inflight[1]); + wire waiting_regs = |(use_regs & (regs_inflight[0] | regs_inflight[1])); + wire waiting = waiting_cpsr | waiting_regs; + assign outstall = (waiting && !inbubble && !flush) || stall; reg delayedflush = 0; always @(posedge clk) -- 2.43.0 From d43b0ab9a916f24601dd987fa84eb6e629b1679d Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Sat, 24 Jan 2009 04:31:18 -0500 Subject: [PATCH 13/16] Fetch: Fix async reset to actually not do it wrong. --- Fetch.v | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/Fetch.v b/Fetch.v index 918e53c..aa9bd7c 100644 --- a/Fetch.v +++ b/Fetch.v @@ -16,8 +16,10 @@ module Fetch( reg qjmp = 0; /* A jump has been queued up while we were waiting. */ reg [31:0] qjmppc; - always @(posedge clk) - if ((rd_wait || stall) && jmp) + always @(posedge clk or negedge Nrst) + if (!Nrst) + qjmp <= 0; + else if ((rd_wait || stall) && jmp) {qjmp,qjmppc} <= {jmp, jmppc}; else if (!rd_wait && !stall && qjmp) /* It has already been intoed. */ {qjmp,qjmppc} <= {1'b0, 32'hxxxxxxxx}; @@ -36,18 +38,10 @@ module Fetch( assign rd_addr = reqpc; assign rd_req = 1; - always @(negedge Nrst) - begin - pc <= 32'hFFFFFFFC; - qjmp <= 0; - bubble <= 1; - end - - always @(posedge clk) + always @(posedge clk or negedge Nrst) begin if (!Nrst) begin pc <= 32'hFFFFFFFC; - qjmp <= 0; bubble <= 1; end else if (!stall) begin -- 2.43.0 From fd003c7a793fb17fb6dc7ba52873b883b28a578b Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Sat, 24 Jan 2009 05:08:28 -0500 Subject: [PATCH 14/16] System, Terminal: Provide real-world outputs on non-Verilator to avoid optimizing the whole system to nothing. --- Terminal.v | 20 +++++++++++++++++++- system.v | 17 +++++++++++++++-- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/Terminal.v b/Terminal.v index dd041d0..9ddd5d3 100644 --- a/Terminal.v +++ b/Terminal.v @@ -7,7 +7,14 @@ module Terminal( output reg cp_busy, input cp_rnw, output reg [31:0] cp_read = 0, - input [31:0] cp_write); + input [31:0] cp_write +`ifdef verilator +`else + , output reg [8:0] sys_odata = 0, + input [8:0] sys_idata, + output reg sys_tookdata = 0 +`endif +); /* Terminal pretends to be cp5. */ reg towrite = 0; @@ -41,5 +48,16 @@ module Terminal( $c("{extern void term_output(unsigned char d); term_output(",data,");}"); else if (didread || !indata[8]) indata = $c("({extern unsigned int term_input(); term_input();})"); +`else + always @(posedge clk) + begin + sys_odata = {towrite,data}; + if (didread || !indata[8]) + begin + indata = sys_idata; + sys_tookdata = 1; + end else + sys_tookdata = 0; + end `endif endmodule diff --git a/system.v b/system.v index 07adfd8..f134ffc 100644 --- a/system.v +++ b/system.v @@ -1,7 +1,15 @@ `define BUS_ICACHE 1 `define BUS_DCACHE 0 -module System(input clk); +module System(input clk +`ifdef verilator +`else + , output wire [8:0] sys_odata, + input [8:0] sys_idata, + output wire sys_tookdata +`endif + ); + wire [7:0] bus_req; wire [7:0] bus_ack; wire [31:0] bus_addr; @@ -208,7 +216,12 @@ module System(input clk); Terminal terminal( .clk(clk), .cp_req(cp_req), .cp_insn(cp_insn), .cp_ack(cp_ack_terminal), .cp_busy(cp_busy_terminal), .cp_rnw(cp_rnw), - .cp_read(cp_read_terminal), .cp_write(cp_write)); + .cp_read(cp_read_terminal), .cp_write(cp_write) +`ifdef verilator +`else + , .sys_odata(sys_odata), .sys_tookdata(sys_tookdata), .sys_idata(sys_idata) +`endif + ); Writeback writeback( .clk(clk), -- 2.43.0 From 2b5c79c05898ff20b0c04cd78bccb2580f6c8331 Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Sat, 24 Jan 2009 05:37:43 -0500 Subject: [PATCH 15/16] DCache, ICache: Make cache_data a 1-D array to enable better synthesizability on Xilinx. --- BlockRAM.v | 4 ++-- DCache.v | 30 +++++++++++++++--------------- ICache.v | 36 +++++++++++++++++------------------- ram.hex | 2 +- 4 files changed, 35 insertions(+), 37 deletions(-) diff --git a/BlockRAM.v b/BlockRAM.v index e0eceeb..091c749 100644 --- a/BlockRAM.v +++ b/BlockRAM.v @@ -31,11 +31,11 @@ module BlockRAM( always @(posedge clk) begin if (bus_wr && decode) - data[ramaddr[13:2]] = bus_wdata; + data[ramaddr[13:2]] <= bus_wdata; /* This is not allowed to be conditional -- stupid Xilinx * blockram. */ - temprdata <= data[ramaddr[13:2]]; + temprdata <= (bus_wr && decode) ? bus_wdata : data[ramaddr[13:2]]; lastread <= ramaddr; end endmodule diff --git a/DCache.v b/DCache.v index f4dff5a..aec6ae6 100644 --- a/DCache.v +++ b/DCache.v @@ -29,7 +29,7 @@ module DCache( reg cache_valid [15:0]; reg [21:0] cache_tags [15:0]; - reg [31:0] cache_data [15:0 /* line */] [15:0 /* word */]; + reg [31:0] cache_data [255:0 /* {line,word} */]; integer i; initial @@ -48,7 +48,7 @@ module DCache( wire cache_hit = cache_valid[idx] && (cache_tags[idx] == tag); - wire [31:0] curdata = cache_data[idx][didx_word]; + wire [31:0] curdata = cache_data[{idx,didx_word}]; always @(*) begin rw_wait = (rd_req && !cache_hit) || (wr_req && (!bus_ack || !bus_ready)); rd_data = curdata; @@ -79,18 +79,18 @@ module DCache( prev_addr <= {addr[31:6], 6'b0}; if (rd_req && (cache_fill_pos != 0) && ((prev_addr != {addr[31:6], 6'b0}) || cache_hit)) /* If this wasn't from the same line, or we've moved on somehow, reset the fill circuitry. */ cache_fill_pos <= 0; - else if (rd_req && !cache_hit) begin - if (bus_ready && bus_ack) begin /* Started the fill, and we have data. */ - $display("DCACHE: FILL: rd addr %08x; bus addr %08x; bus data %08x, bus_req %d, bus_ack %d", addr, bus_addr, bus_rdata, bus_req, bus_ack); - cache_data[idx][cache_fill_pos] <= bus_rdata; - cache_fill_pos <= cache_fill_pos + 1; - if (cache_fill_pos == 15) begin /* Done? */ - cache_tags[idx] <= tag; - cache_valid[idx] <= 1; - end else - cache_valid[idx] <= 0; - end - end else if (wr_req && cache_hit) - cache_data[idx][addr[5:2]] <= wr_data; + else if (rd_req && !cache_hit && bus_ready && bus_ack) begin /* Started the fill, and we have data. */ + $display("DCACHE: FILL: rd addr %08x; bus addr %08x; bus data %08x, bus_req %d, bus_ack %d", addr, bus_addr, bus_rdata, bus_req, bus_ack); + cache_fill_pos <= cache_fill_pos + 1; + if (cache_fill_pos == 15) begin /* Done? */ + cache_tags[idx] <= tag; + cache_valid[idx] <= 1; + end else + cache_valid[idx] <= 0; + end + + /* Split this out because XST is kind of silly about this sort of thing. */ + if ((rd_req && !cache_hit && bus_ready && bus_ack) || (wr_req && cache_hit)) + cache_data[wr_req ? {idx,addr[5:2]} : {idx,cache_fill_pos}] <= wr_req ? wr_data : bus_rdata; end endmodule diff --git a/ICache.v b/ICache.v index e6754b7..8b9eac3 100644 --- a/ICache.v +++ b/ICache.v @@ -30,7 +30,7 @@ module ICache( reg cache_valid [15:0]; reg [21:0] cache_tags [15:0]; - reg [31:0] cache_data [15:0 /* line */] [15:0 /* word */]; + reg [31:0] cache_data [255:0 /* {line, word} */]; //synthesis attribute ram_style of cache_data is distributed integer i; initial @@ -48,12 +48,6 @@ module ICache( reg [31:0] prev_rd_addr = 32'hFFFFFFFF; wire cache_hit = cache_valid[rd_idx] && (cache_tags[rd_idx] == rd_tag); - - wire [31:0] curdata = cache_data[rd_idx][rd_didx_word]; - always @(*) begin - rd_wait = rd_req && !cache_hit; - rd_data = curdata; - end reg [3:0] cache_fill_pos = 0; assign bus_req = rd_req && !cache_hit; /* xxx, needed for Verilator */ @@ -65,23 +59,27 @@ module ICache( bus_addr = 0; bus_rd = 0; end + + wire [31:0] curdata = cache_data[{rd_idx,rd_didx_word}]; + always @(*) begin + rd_wait = rd_req && !cache_hit; + rd_data = curdata; + end always @(posedge clk) begin prev_rd_addr <= {rd_addr[31:6], 6'b0}; if (cache_fill_pos != 0 && ((prev_rd_addr != {rd_addr[31:6], 6'b0}) || cache_hit)) /* If this wasn't from the same line, or we've moved on somehow, reset the fill circuitry. */ cache_fill_pos <= 0; - else if (rd_req && !cache_hit) begin - if (bus_ack && bus_ready) begin /* Started the fill, and we have data. */ - $display("ICACHE: FILL: rd addr %08x; bus addr %08x; bus data %08x", rd_addr, bus_addr, bus_rdata); - cache_data[rd_idx][cache_fill_pos] <= bus_rdata; - cache_fill_pos <= cache_fill_pos + 1; - if (cache_fill_pos == 15) begin /* Done? */ - cache_tags[rd_idx] <= rd_tag; - cache_valid[rd_idx] <= 1; - $display("ICACHE: Fill complete for line %x, tag %x", rd_idx, rd_tag); - end else - cache_valid[rd_idx] <= 0; - end + else if (rd_req && !cache_hit && bus_ack && bus_ready) begin + $display("ICACHE: FILL: rd addr %08x; bus addr %08x; bus data %08x", rd_addr, bus_addr, bus_rdata); + cache_data[{rd_idx,cache_fill_pos}] <= bus_rdata; + cache_fill_pos <= cache_fill_pos + 1; + if (cache_fill_pos == 15) begin /* Done? */ + cache_tags[rd_idx] <= rd_tag; + cache_valid[rd_idx] <= 1; + $display("ICACHE: Fill complete for line %x, tag %x", rd_idx, rd_tag); + end else + cache_valid[rd_idx] <= 0; end end endmodule diff --git a/ram.hex b/ram.hex index 96b3cdf..6d0fcf5 120000 --- a/ram.hex +++ b/ram.hex @@ -1 +1 @@ -tests/u-boot.hex \ No newline at end of file +tests/testbench.hex \ No newline at end of file -- 2.43.0 From cc1ce5b3e8f2d357106c2d3da355360f99c6c9c3 Mon Sep 17 00:00:00 2001 From: Joshua Wise Date: Sun, 25 Jan 2009 03:39:09 -0500 Subject: [PATCH 16/16] Memory: Fix up a constant that was typoed and malformed. --- Memory.v | 1 + 1 file changed, 1 insertion(+) diff --git a/Memory.v b/Memory.v index eccddb2..5269f64 100644 --- a/Memory.v +++ b/Memory.v @@ -125,6 +125,7 @@ module Memory( busaddr = 32'hxxxxxxxx; data_size = 3'bxxx; outstall = 1'b0; + st_read = 4'hx; do_rd_data_latch = 0; next_write_reg = write_reg; next_write_num = write_num; -- 2.43.0