From 7569f68cbb221e1e21fb6c20db53f177f8323a31 Mon Sep 17 00:00:00 2001 From: adam Date: Mon, 27 Oct 2008 07:36:53 +0100 Subject: [PATCH] add flush support to ships --- ships/Alu.ship | 127 ++++++++++++++++++++++++++++++--------------- ships/CarrySaveAdder.ship | 4 +- ships/DDR2.ship | 79 ++++++++++++++++++++++++++++ ships/DRAM.ship | 28 +++++----- ships/Debug.ship | 30 ++++------- ships/Fifo.ship | 22 +++++--- ships/Lut3.ship | 9 ++-- ships/Memory.ship | 38 +++++++++++--- ships/Rotator.ship | 5 +- ships/Video.ship | 8 +-- 10 files changed, 251 insertions(+), 99 deletions(-) create mode 100644 ships/DDR2.ship diff --git a/ships/Alu.ship b/ships/Alu.ship index 9cc5e77..2089b8a 100644 --- a/ships/Alu.ship +++ b/ships/Alu.ship @@ -11,6 +11,9 @@ data in: inOp constant MAX: 4 constant MIN: 5 constant CMP: 6 + constant DROP1: 7 + constant DROP2: 8 + constant MAXMERGE: 9 data out: out @@ -36,13 +39,16 @@ is then made available at {\tt out}. \subsection*{C-Flag} \begin{verbatim} -IN1 - undefined -IN2 - undefined -ADD - carry-out -SUB - undefined -MAX - 0 if in1>in2, else 1 -MIN - 1 if in1>in2, else 0 -CMP - 0 if in1!=in2, else 1 +IN1 - undefined; drain in1 only +IN2 - undefined; drain in2 only +ADD - carry-out +SUB - undefined +MAX - if in1>in2 cflag=0 and drain in1, else cflag=1 and drain in2 +MIN - if in1>in2 cflag=1 and drain in2, else cflag=0 and drain in1 +CMP - if in1==in2 cflag=1, else cflag=0 +DROP1 - consume in1, produce no output +DROP2 - consume in2, produce no output +MAXMERGE - if (in1<0 && in2<0) consume both, emit either, cflag=undef else act as MAX \end{verbatim} \subsection*{To Do} @@ -56,29 +62,56 @@ yet implemented. == Fleeterpreter ==================================================== public void service() { - if (box_in1.dataReadyForShip() && + if (box_inOp.dataReadyForShip() && + box_in1.dataReadyForShip() && box_in2.dataReadyForShip() && - box_inOp.dataReadyForShip() && box_out.readyForDataFromShip()) { - long a = box_in1.removeDataForShip(); - long b = box_in2.removeDataForShip(); + long a; + long b; long op = box_inOp.removeDataForShip(); switch((int)op) { - case 0: box_out.addDataFromShip(a); // IN1 + case 0: + a = box_in1.removeDataForShip(); + box_out.addDataFromShip(a); // IN1 break; - case 1: box_out.addDataFromShip(b); // IN2 + case 1: + b = box_in2.removeDataForShip(); + box_out.addDataFromShip(b); // IN2 break; - case 2: box_out.addDataFromShip(a+b); // ADD + case 2: + a = box_in1.removeDataForShip(); + b = box_in2.removeDataForShip(); + box_out.addDataFromShip(a+b); // ADD break; - case 3: box_out.addDataFromShip(a-b); // SUB + case 3: + a = box_in1.removeDataForShip(); + b = box_in2.removeDataForShip(); + box_out.addDataFromShip(a-b); // SUB break; - case 4: box_out.addDataFromShip(Math.max(a,b)); // MAX + case 4: + a = box_in1.peekDataForShip(); + b = box_in2.peekDataForShip(); + box_out.addDataFromShip(Math.max(a,b)); // MAX box_out.flag_c = !(a>b); + if (ab; + if (a>b) box_in1.removeDataForShip(); else box_in2.removeDataForShip(); break; - default: box_out.addDataFromShip(0); + case 6: + a = box_in1.removeDataForShip(); + b = box_in2.removeDataForShip(); + box_out.addDataFromShip(0); // CMP + box_out.flag_c = a==b; + break; + default: + a = box_in1.removeDataForShip(); + b = box_in2.removeDataForShip(); + box_out.addDataFromShip(0); break; } } @@ -97,23 +130,25 @@ public void service() { wire eq; wire cout; - assign isplus = inOp_d[2:0]==2; - assign cin = isplus ? 0 : 1; - assign in2_inverted = isplus ? in2_d : ~in2_d; - assign sum = {in1_d,cin} + {in2_inverted,cin}; - assign res = sum[`DATAWIDTH:1]; - assign greater = !res[`DATAWIDTH-1]; - assign eq = in1_d == in2_d; - assign cout = sum[`DATAWIDTH]; + assign isplus = inOp_d[2:0]==2; + assign cin = isplus ? 0 : 1; + assign in2_inverted = isplus ? in2_d : ~in2_d; + assign sum = {in1_d,cin} + {in2_inverted,cin}; + assign res = sum[`DATAWIDTH:1]; + assign greater = !res[`DATAWIDTH-1]; + assign both_negative = in1_d[`DATAWIDTH-1] && in2_d[`DATAWIDTH-1]; + assign eq = in1_d == in2_d; + assign cout = sum[`DATAWIDTH]; assign out_d_[`DATAWIDTH] = (inOp_d==0) ? 1'b0 : (inOp_d==1) ? 1'b0 : (inOp_d==2) ? cout : - (inOp_d==3) ? 1'b0 : + (inOp_d==3) ? cout : (inOp_d==4) ? ~greater : (inOp_d==5) ? greater : (inOp_d==6) ? eq : + (inOp_d==9) ? ~greater : 0; assign out_d_[(`DATAWIDTH-1):0] = @@ -124,20 +159,34 @@ public void service() { (inOp_d==4) ? (greater ? in1_d : in2_d) : (inOp_d==5) ? (greater ? in2_d : in1_d) : (inOp_d==6) ? {{ (`DATAWIDTH-1) {1'b0 }}, eq } : + (inOp_d==9) ? (both_negative ? in1_d : (greater ? in1_d : in2_d)) : 0; always @(posedge clk) begin if (!rst) begin `reset end else begin - if (!in1_r && in1_a) in1_a <= 0; - if (!in2_r && in2_a) in2_a <= 0; - if (!inOp_r && inOp_a) inOp_a <= 0; + `flush + if (!in1_r_ && in1_a) in1_a <= 0; + if (!in2_r_ && in2_a) in2_a <= 0; + if (!inOp_r_ && inOp_a) inOp_a <= 0; if (out_r && out_a) begin - out_r <= 0; - in1_a <= 1; - in2_a <= 1; + out_r <= 0; inOp_a <= 1; + + if (inOp_d==0) in1_a <= 1; + else if (inOp_d==1) in2_a <= 1; + else if (inOp_d==9 && both_negative) begin in1_a <= 1; in2_a <= 1; end + else if (inOp_d==4 && greater) in1_a <= 1; + else if (inOp_d==5 && greater) in2_a <= 1; + else if (inOp_d==9 && greater) in1_a <= 1; + else if (inOp_d==4 && !greater) in2_a <= 1; + else if (inOp_d==5 && !greater) in1_a <= 1; + else if (inOp_d==9 && !greater) in2_a <= 1; + else begin + in1_a <= 1; + in2_a <= 1; + end end if (!out_r && !out_a && in1_r && !in1_a && in2_r && !in2_a && inOp_r && !inOp_a) begin out_r <= 1; @@ -161,21 +210,19 @@ public void service() { #expect 9 #expect 0 #expect 0 -#expect 0 -#expect 1 #expect 1 debug.in: set ilc=*; recv, deliver; alu.in1: set word= 9; - set ilc=7; + set ilc=5; deliver; set word= 9; deliver; alu.in2: set word= 8; - set ilc=7; + set ilc=5; deliver; set word= 9; deliver; @@ -188,8 +235,6 @@ alu.inOp: set word= Alu.inOp[SUB]; deliver; set word= Alu.inOp[IN1]; deliver; set word= Alu.inOp[IN2]; deliver; - -alu.inOp: set word= Alu.inOp[MIN]; deliver; set word= Alu.inOp[MAX]; deliver; set word= Alu.inOp[CMP]; deliver; @@ -208,13 +253,13 @@ alu.out: [!a] set word= 0; send to debug.in; - collect, send to debug.in; // CMP + collect; // CMP set flags a=c, b=b; [a] set word= 1; [!a] set word= 0; send to debug.in; - collect, send to debug.in; // CMP + collect; // CMP set flags a=c, b=b; [a] set word= 1; [!a] set word= 0; diff --git a/ships/CarrySaveAdder.ship b/ships/CarrySaveAdder.ship index 7bbb9e7..4371afd 100644 --- a/ships/CarrySaveAdder.ship +++ b/ships/CarrySaveAdder.ship @@ -43,7 +43,8 @@ public void service() { `reset state <= 0; end else begin - if (!in_r && in_a) in_a <= 0; + `flush + if (!in_r_ && in_a) in_a <= 0; if (out_r && out_a) out_r <= 0; if (!out_r && !out_a && state==3) begin out_d <= { 1'b0, temp }; @@ -66,7 +67,6 @@ public void service() { end == Test ============================================================== - // expected output #expect 0x3c4bc6 #expect 0x1796d2 diff --git a/ships/DDR2.ship b/ships/DDR2.ship new file mode 100644 index 0000000..b594c87 --- /dev/null +++ b/ships/DDR2.ship @@ -0,0 +1,79 @@ +ship: DDR2 + +== Ports =========================================================== +data in: inAddrRead +data in: inAddrWrite +data in: inDataWrite + +data out: out + +== TeX ============================================================== + +== Fleeterpreter ==================================================== + public void service() { } +== FleetSim ============================================================== + +== FPGA ============================================================== + + reg ddr2_addr_r; + reg ddr2_isread; + reg ddr2_write_data_push; + reg ddr2_read_data_pop; + reg [`DATAWIDTH:0] out_d; + + assign ddr2_addr_r_ = ddr2_addr_r; + assign ddr2_isread_ = ddr2_isread; + assign ddr2_addr_ = !ddr2_isread ? inAddrWrite_d[31:0] : inAddrRead_d[31:0]; + assign ddr2_write_data_push_ = ddr2_write_data_push; + assign ddr2_read_data_pop_ = ddr2_read_data_pop; + assign ddr2_write_data_ = { inDataWrite_d[31:5], inDataWrite_d[4], inDataWrite_d[35:0] }; +// assign ddr2_write_data_ = inDataWrite_d[(`DATAWIDTH-1):0]; + assign out_d_ = out_d; + + always @(posedge clk) begin + + if (!rst) begin + `reset + ddr2_isread <= 0; + ddr2_addr_r <= 0; + ddr2_read_data_pop <= 0; + + end else begin + `flush + + if (!inAddrRead_r_ && inAddrRead_a) inAddrRead_a <= 0; + if (!inDataWrite_r_ && inDataWrite_a) inDataWrite_a <= 0; + if (!inAddrWrite_r_ && inAddrWrite_a) inAddrWrite_a <= 0; + if ( out_r && out_a) out_r <= 0; + + if (ddr2_addr_r && !ddr2_addr_a) begin + // busy + end else if (ddr2_addr_r && ddr2_addr_a && !ddr2_isread) begin + ddr2_addr_r <= 0; + inAddrWrite_a <= 1; + inDataWrite_a <= 1; + out_d <= { 1'b1, 37'b0 }; + out_r <= 1; + end else if (ddr2_addr_r && ddr2_addr_a && ddr2_isread) begin + ddr2_addr_r <= 0; + inAddrRead_a <= 1; + out_d <= { 1'b0, ddr2_read_data[36:0] }; + out_r <= 1; + end else if (!out_r && !out_a && inAddrWrite_r && !inAddrWrite_a && inDataWrite_r && !inDataWrite_a && !ddr2_addr_r && !ddr2_addr_a) begin + ddr2_addr_r <= 1; + ddr2_isread <= 0; + end else if (!out_r && !out_a && inAddrRead_r && !inAddrRead_a && !ddr2_addr_r && !ddr2_addr_a) begin + ddr2_addr_r <= 1; + ddr2_isread <= 1; + end + end + end + + +== Test ======================================================== +#skip + +== Constants ======================================================== + +== Contributors ========================================================= +Adam Megacz diff --git a/ships/DRAM.ship b/ships/DRAM.ship index b3758dc..d5d5338 100644 --- a/ships/DRAM.ship +++ b/ships/DRAM.ship @@ -15,20 +15,21 @@ data out: out == FPGA ============================================================== - // FIXME: use the other chip (64-bit data bus) - reg dram_addr_r; reg dram_isread; reg dram_write_data_push; reg dram_read_data_pop; - reg [`DATAWIDTH-1:0] out_d; + reg [`DATAWIDTH:0] out_d; + wire [31:0] dram_addr__; assign dram_addr_r_ = dram_addr_r; assign dram_isread_ = dram_isread; - assign dram_addr_ = !dram_isread ? inAddrWrite_d[31:0] : inAddrRead_d[31:0]; + assign dram_addr__ = !dram_isread ? inAddrWrite_d[31:0] : inAddrRead_d[31:0]; + assign dram_addr_ = { dram_addr__[30:6], 1'b0, dram_addr__[5:0] }; assign dram_write_data_push_ = dram_write_data_push; assign dram_read_data_pop_ = dram_read_data_pop; - assign dram_write_data_ = inDataWrite_d[31:0]; + assign dram_write_data_ = inDataWrite_d; +// assign dram_write_data_ = inDataWrite_d[(`DATAWIDTH-1):0]; assign out_d_ = out_d; always @(posedge clk) begin @@ -40,11 +41,12 @@ data out: out dram_read_data_pop <= 0; end else begin + `flush - if (!inAddrRead_r && inAddrRead_a) inAddrRead_a <= 0; - if (!inDataWrite_r && inDataWrite_a) inDataWrite_a <= 0; - if (!inAddrWrite_r && inAddrWrite_a) inAddrWrite_a <= 0; - if ( out_r && out_a) out_r <= 0; + if (!inAddrRead_r_ && inAddrRead_a) inAddrRead_a <= 0; + if (!inDataWrite_r_ && inDataWrite_a) inDataWrite_a <= 0; + if (!inAddrWrite_r_ && inAddrWrite_a) inAddrWrite_a <= 0; + if ( out_r && out_a) out_r <= 0; if (dram_addr_r && !dram_addr_a) begin // busy @@ -52,15 +54,17 @@ data out: out dram_addr_r <= 0; inAddrWrite_a <= 1; inDataWrite_a <= 1; + out_d <= { 1'b1, 37'b0 }; + out_r <= 1; end else if (dram_addr_r && dram_addr_a && dram_isread) begin dram_addr_r <= 0; inAddrRead_a <= 1; - out_d <= dram_read_data; + out_d <= { 1'b0, dram_read_data[36:0] }; out_r <= 1; - end else if (inAddrWrite_r && !inAddrWrite_a && inDataWrite_r && !inDataWrite_a && !dram_addr_r && !dram_addr_a) begin + end else if (!out_r && !out_a && inAddrWrite_r && !inAddrWrite_a && inDataWrite_r && !inDataWrite_a && !dram_addr_r && !dram_addr_a) begin dram_addr_r <= 1; dram_isread <= 0; - end else if (inAddrRead_r && !inAddrRead_a && !out_r && !out_a && !dram_addr_r && !dram_addr_a) begin + end else if (!out_r && !out_a && inAddrRead_r && !inAddrRead_a && !dram_addr_r && !dram_addr_a) begin dram_addr_r <= 1; dram_isread <= 1; end diff --git a/ships/Debug.ship b/ships/Debug.ship index c8e102e..c3ea67d 100644 --- a/ships/Debug.ship +++ b/ships/Debug.ship @@ -30,25 +30,17 @@ public void service() { == FPGA ============================================================== -module debug (clk, rst, - data_debug_data_r, data_debug_data_a, data_debug_data, - data_debug_out_r, data_debug_out_a, data_debug_out ); - input clk; - input rst; - - input data_debug_data_r; - output data_debug_data_a; - input [`DATAWIDTH:0] data_debug_data; - - output data_debug_out_r; - input data_debug_out_a; - output [`DATAWIDTH:0] data_debug_out; - - assign data_debug_out_r = data_debug_data_r; - assign data_debug_data_a = data_debug_out_a; - assign data_debug_out = data_debug_data; - -endmodule + assign out_d_ = in_d; + assign out_r_ = in_r; + + always @(posedge clk) begin + if (!rst) begin + `reset + end else begin + `flush + in_a <= out_a; + end + end == Test ================================================================ #expect 25 diff --git a/ships/Fifo.ship b/ships/Fifo.ship index 0a620b2..80dcebc 100644 --- a/ships/Fifo.ship +++ b/ships/Fifo.ship @@ -31,16 +31,22 @@ at least 16 words. == FPGA ============================================================== - input [(`DATAWIDTH-1):0] in_d; - output [(`DATAWIDTH-1):0] out_d_; - input in_r; - output in_a_; - output out_r_; - input out_a; + wire in_a__; + wire out_r__; fifo8x37 fifo8x37(clk, rst, - in_r, in_a_, in_d, - out_r_, out_a, out_d_); + in_r, in_a__, in_d, + out_r__, out_a, out_d_); + + always @(posedge clk) begin + if (!rst) begin + `reset + end else begin + `flush + out_r <= out_r__; + in_a <= in_a__; + end + end == Test ================================================================= diff --git a/ships/Lut3.ship b/ships/Lut3.ship index 3820874..dd7831b 100644 --- a/ships/Lut3.ship +++ b/ships/Lut3.ship @@ -77,10 +77,11 @@ is considered ``bit zero''). if (!rst) begin `reset end else begin - if (!in1_r && in1_a) in1_a <= 0; - if (!in2_r && in2_a) in2_a <= 0; - if (!in3_r && in3_a) in3_a <= 0; - if (!inLut_r && inLut_a) inLut_a <= 0; + `flush + if (!in1_r_ && in1_a) in1_a <= 0; + if (!in2_r_ && in2_a) in2_a <= 0; + if (!in3_r_ && in3_a) in3_a <= 0; + if (!inLut_r_ && inLut_a) inLut_a <= 0; if (out_r && out_a) begin in1_a <= 1; in2_a <= 1; diff --git a/ships/Memory.ship b/ships/Memory.ship index 135102a..f97347c 100644 --- a/ships/Memory.ship +++ b/ships/Memory.ship @@ -12,7 +12,25 @@ data out: out The {\tt Memory} ship represents an interface to a storage space, which can be used to read from it or write to it. This storage space -might be a fast on-chip cache, off chip DRAM, or perhaps even a disk drive. +might be a fast on-chip cache, off chip DRAM, or perhaps even a disk +drive. + +Generally, distinct {\tt Memory} ships do not access the same backing +storage, although this is not strictly prohibited. + +Each {\tt Memory} ship may have multiple {\it interfaces}, numbered +starting with {\tt 0}. Each interface may have any subset of the +following docks: {\tt inCBD}, {\tt inAddrRead}, {\tt inAddrWrite}, +{\tt inDataWrite}, and {\tt out}. If {\tt inCBD} or {\tt inAddrRead} +is present on an interface, then {\tt out} must be present as well. +If {\tt inAddrWrite} is present then {\tt inDataWrite} must be present +as well. + +Each interface serializes the operations presented to it; this means +that an interface with both read and write capabilities will not be +able to read and write concurrently. Instead, a {\tt Memory} ship +with the ability to read and write concurrently should have two +interfaces, one which is read-only and one which is write-only. There may be multiple {\tt Memory} ships which interface to the same physical storage space. An implementation of Fleet must provide @@ -44,7 +62,8 @@ inCount=size}. \subsection*{Reading} When a word is delivered to {\tt inAddrRead}, the word residing in -memory at that address is provided at {\tt out}. +memory at that address is provided at {\tt out}. The {\tt c-flag} at +the {\tt out} port is set to zero. \subsection*{Writing} @@ -52,7 +71,8 @@ When a word is delivered to {\tt inAddrWrite} and {\tt inDataWrite}, the word at {\tt inDataWrite} is written to the address specified by {\tt inAddrWrite}. Once the word is successfully committed to memory, the value {\tt inAddr+inStride} is provided at {\tt out} (that is, the -address of the next word to be written). +address of the next word to be written). The {\tt c-flag} at +the {\tt out} port is set to one. \subsection*{To Do} @@ -171,12 +191,13 @@ sequence guarantee problem mentioned in the previous paragraph. write_flag <= 0; dispatching_cbd <= 0; end else begin + `flush write_flag <= 0; - if (!inAddrRead_r && inAddrRead_a) inAddrRead_a <= 0; - if (!inDataWrite_r && inDataWrite_a) inDataWrite_a <= 0; - if (!inAddrWrite_r && inAddrWrite_a) inAddrWrite_a <= 0; - if (!inCBD_r && inCBD_a) inCBD_a <= 0; + if (!inAddrRead_r_ && inAddrRead_a) inAddrRead_a <= 0; + if (!inDataWrite_r_ && inDataWrite_a) inDataWrite_a <= 0; + if (!inAddrWrite_r_ && inAddrWrite_a) inAddrWrite_a <= 0; + if (!inCBD_r_ && inCBD_a) inCBD_a <= 0; // assumes we never want a zero-length codebag if ( inCBD_r && !inCBD_a && !out_r && !out_a) begin @@ -216,6 +237,9 @@ sequence guarantee problem mentioned in the previous paragraph. == Test ============================================================== +// FIXME: test c-flag at out dock +// FIXME: rename to inCBD0, inAddrWrite0, etc + // expected output #expect 12 #expect 13 diff --git a/ships/Rotator.ship b/ships/Rotator.ship index 2e2270b..0049ab8 100644 --- a/ships/Rotator.ship +++ b/ships/Rotator.ship @@ -46,8 +46,9 @@ public void service() { if (!rst) begin `reset end else begin - if (!in_r && in_a && !inAmount_r) in_a <= 0; - if (!inAmount_r && inAmount_a) inAmount_a <= 0; + `flush + if (!in_r_ && in_a && !inAmount_r) in_a <= 0; + if (!inAmount_r_ && inAmount_a) inAmount_a <= 0; if (out_r && out_a) out_r <= 0; if (in_r && !in_a && inAmount_r && !inAmount_a && !out_r && !out_a) begin in_a <= 1; diff --git a/ships/Video.ship b/ships/Video.ship index 82aac06..ec54993 100644 --- a/ships/Video.ship +++ b/ships/Video.ship @@ -92,12 +92,12 @@ data in: inData if (!rst) begin `reset end else begin - + `flush vga_pixel_a <= vga_pixel_r; - if (!inData_r && inData_a) inData_a <= 0; - if (!inX_r && inX_a) inX_a <= 0; - if (!inY_r && inY_a) inY_a <= 0; + if (!inData_r_ && inData_a) inData_a <= 0; + if (!inX_r_ && inX_a) inX_a <= 0; + if (!inY_r_ && inY_a) inY_a <= 0; if (inX_r && !inX_a && inY_r && !inY_a && inData_r && !inData_a) begin we <= 1; inX_a <= 1; -- 1.7.10.4