total rewrite of Memory.ship FPGA code
authoradam <adam@megacz.com>
Wed, 19 Nov 2008 10:29:32 +0000 (11:29 +0100)
committeradam <adam@megacz.com>
Wed, 19 Nov 2008 10:29:32 +0000 (11:29 +0100)
ships/Memory.ship

index 416d070..5ccced3 100644 (file)
@@ -161,129 +161,112 @@ sequence guarantee problem mentioned in the previous paragraph.
 
 == FPGA ==============================================================
 
-  reg                              write_flag;
-  reg [(`BRAM_ADDR_WIDTH-1):0]     cursor;
-  wire [(`BRAM_ADDR_WIDTH-1):0]   addr1;
-
-  // bram //////////////////////////////////////////////////////////////////////////////
-`define BRAM_ADDR_WIDTH 14
-`define BRAM_SIZE (1<<(`BRAM_ADDR_WIDTH))
-
-    reg    [(`WORDWIDTH-1):0]       ram [((`BRAM_SIZE)-1):0];
-    reg    [(`BRAM_ADDR_WIDTH-1):0] read_a; 
-    reg    [(`BRAM_ADDR_WIDTH-1):0] read_dpra; 
-    always @(posedge clk) begin 
-        if (write_flag) 
-            ram[addr1] <= inDataWrite_d; 
-        read_a <= addr1; 
-        read_dpra <= cursor; 
-    end
-
-  ////////////////////////////////////////////////////////////////////////////////
-
-  wire [(`WORDWIDTH-1):0] out1;
-  wire [(`WORDWIDTH-1):0] out2;
-
-  assign out1 = ram[read_a]; 
-  assign out2 = ram[read_dpra]; 
-
-  reg [(`CODEBAG_SIZE_BITS-1):0]   counter;
-  initial cursor = 0;
-  initial counter = 0;
+  `define BRAM_ADDR_WIDTH 14
+  `define BRAM_SIZE (1<<(`BRAM_ADDR_WIDTH))
 
-  reg                              out_w;
-  reg                              dispatching_cbd;
-  initial write_flag = 0;
-  initial dispatching_cbd = 0;
+  reg    [(`WORDWIDTH-1):0]       ram [((`BRAM_SIZE)-1):0];
+  reg    [(`BRAM_ADDR_WIDTH-1):0] addr1;
+  reg    [(`BRAM_ADDR_WIDTH-1):0] addr2;
+  reg    [(`WORDWIDTH-1):0]       out1;
+  reg    [(`WORDWIDTH-1):0]       out2;
 
-  assign addr1 = write_flag ? inAddrWrite_d[(`WORDWIDTH-1):0] : inAddrRead_d[(`WORDWIDTH-1):0];
+  reg                             out_w;
+  reg                             write_flag;
+  reg [(`BRAM_ADDR_WIDTH-1):0]    cursor;
+  reg [(`CODEBAG_SIZE_BITS-1):0]  counter;
 
-  assign out_d_ = { out_w , (dispatching_cbd ? out2 : out1) };
+  assign out_d_ = { out_w, out1 };
 
   always @(posedge clk) begin
-
-    write_flag <= 0;
+    write_flag = 0;
 
     if (!rst) begin
       `reset
-      cursor  <= 0;
-      counter <= 0;
-      write_flag <= 0;
-      dispatching_cbd <= 0;
+      cursor      = 0;
+      counter     = 0;
     end else begin
       `flush
       `cleanup
-      write_flag <= 0;
-
-      // assumes we never want a zero-length codebag
-      if (`inCBD_full && `out_empty) begin
-        if (!dispatching_cbd) begin
-          cursor          <= inCBD_d[(`WORDWIDTH-1):(`CODEBAG_SIZE_BITS)];
-          counter         <= 0;
-          dispatching_cbd <= 1;
-        end
-        `fill_out
-        out_w <= 0;
-
-      end else if (`inCBD_full && `out_draining) begin
-        if (counter != inCBD_d[(`CODEBAG_SIZE_BITS-1):0]) begin
-          cursor  <= cursor + 1;
-          counter <= counter + 1;
-        end else begin
-          `drain_inCBD
-          counter <= 0;
-          dispatching_cbd <= 0;
+
+      if (counter!=0) begin
+        if (`out_empty) begin
+          `fill_out
+          out_w    = 0;
+          addr1    = cursor;
+          cursor   = cursor  + 1;
+          counter  = counter - 1;
         end
 
-      end else if (!dispatching_cbd && `out_empty && `inAddrRead_full) begin
+      end else if (`inCBD_full) begin
+        cursor    = inCBD_d[(`WORDWIDTH-1):(`CODEBAG_SIZE_BITS)];
+        counter   = inCBD_d[(`CODEBAG_SIZE_BITS-1):0];
+        addr1     = cursor;
+        `drain_inCBD
+
+      end else if (`out_empty && `inAddrRead_full) begin
+        addr1     = inAddrRead_d[(`WORDWIDTH-1):0];
         `drain_inAddrRead
         `fill_out
-        out_w <= 0;
+        out_w     = 0;
 
-      end else if (!dispatching_cbd && `out_empty && `inAddrWrite_full && `inDataWrite_full) begin
-        // timing note: it's okay to drain here because *_d will still
-        // be valid on the *very next* cycle, which is all we care about
+      end else if (`out_empty && `inAddrWrite_full && `inDataWrite_full) begin
+        write_flag = 1;
         `drain_inAddrWrite
         `drain_inDataWrite
         `fill_out
-        write_flag      <= 1;
-        out_w           <= 1;
+        addr2     = inAddrWrite_d[(`WORDWIDTH-1):0];
+        out_w     = 1;
+
       end
     end
+
+    // this must appear at the end of the block, outside of any if..then's
+    if (write_flag) 
+      ram[addr2] <= inDataWrite_d; 
+    out1 <= ram[addr1];
+    out2 <= ram[addr2]; 
   end
     
 
 
 
 == Test ==============================================================
+// Note: this only tests the read/write interfaces, not the inCBD interface
 // FIXME: test c-flag at out dock
-// FIXME: rename to inCBD0, inAddrWrite0, etc
 
 // expected output
-#expect 12
-#expect 13
-#expect 14
+#expect 10
 
 // ships required in order to run this code
 #ship debug          : Debug
 #ship memory         : Memory
 
-// instructions not in any codebag are part of the "root codebag"
-// which is dispatched when the code is loaded
+memory.inAddrWrite:
+  set word=3;
+  deliver;
+  deliver;
 
-memory.out:
-  set ilc=*;  collect packet, send;
+memory.inDataWrite:
+  set word=4;
+  deliver;
+  set word=10;
+  deliver;
 
-memory.inCBD:
-  set word= BOB;
+memory.inAddrRead:
+  recv token;
+  set word=3;
   deliver;
 
-BOB: {
-  debug.in:
-    set word= 12; deliver;
-    set word= 13; deliver;
-    set word= 14; deliver;
-}
+memory.out:
+  collect;
+  collect;
+  send token to memory.inAddrRead;
+  collect;
+  send to debug.in;
+
+debug.in:
+  set ilc=*;
+  recv, deliver;
 
 
 == Constants ========================================================