migrate verilog into ship files
[fleet.git] / ships / Dscratch.ship
index 9b05a11..08c4413 100644 (file)
@@ -36,7 +36,94 @@ token out:   write_done
     }
 
 == ArchSim ==============================================================
+
 == FPGA ==============================================================
+`include "macros.v"
+`define BRAM_ADDR_WIDTH 14
+`define BRAM_DATA_WIDTH `DATAWIDTH
+`define BRAM_NAME dscratch_bram
+`include "bram.inc"
+
+module dscratch (clk, 
+               read_addr_r,    read_addr_a_,   read_addr_d,
+               read_data_r_,   read_data_a,    read_data_d_,
+               write_addr_r,   write_addr_a_,  write_addr_d,
+               write_data_r,   write_data_a_,  write_data_d,
+               write_done_r_,  write_done_a,   write_done_d_
+              );
+
+  input  clk;
+  `input(read_addr_r,    read_addr_a,   read_addr_a_,   [(`DATAWIDTH-1):0],  read_addr_d)
+  `output(read_data_r,   read_data_r_,  read_data_a,    [(`DATAWIDTH-1):0],  read_data_d_)
+  `defreg(read_data_d_,                                 [(`DATAWIDTH-1):0],  read_data_d)
+
+  `input(write_addr_r,   write_addr_a,  write_addr_a_,  [(`DATAWIDTH-1):0],  write_addr_d)
+  `input(write_data_r,   write_data_a,  write_data_a_,  [(`DATAWIDTH-1):0],  write_data_d)
+  `output(write_done_r,  write_done_r_, write_done_a,   [(`DATAWIDTH-1):0],  write_done_d_)
+  `defreg(write_done_d_,                                [(`DATAWIDTH-1):0],  write_done_d)
+
+  reg                           bram_we;
+  wire                          bram_we_;
+  assign bram_we_ = bram_we;
+  wire [(`BRAM_DATA_WIDTH-1):0] bram_read_data;
+  reg  [(`BRAM_ADDR_WIDTH-1):0] bram_write_address;
+  wire [(`BRAM_ADDR_WIDTH-1):0] bram_read_address;
+  reg  [(`BRAM_DATA_WIDTH-1):0] bram_write_data;
+  wire [(`BRAM_DATA_WIDTH-1):0] bram_write_data_;
+  assign bram_write_data_ = bram_write_data;
+  `BRAM_NAME mybram(clk,
+                    bram_we_,          bram_write_address,
+                    bram_read_address, bram_write_data_,
+                    not_connected,     bram_read_data);
+
+  reg send_done;
+
+  reg have_read;    initial have_read = 0;
+  reg read_pending; initial read_pending = 0;
+  assign bram_read_address = read_addr_d;
+
+  always @(posedge clk) begin
+    bram_we = 0;
+    if (send_done) begin
+      `onwrite(write_done_r, write_done_a)
+        send_done = 0;
+      end
+    end else begin
+      if (!write_addr_r && write_addr_a) write_addr_a = 0;
+      if (!write_data_r && write_data_a) write_data_a = 0;
+      if (write_addr_r && write_data_r) begin
+        write_addr_a = 1;
+        write_data_a = 1;
+        bram_we = 1;
+        send_done = 1;
+        bram_write_address = write_addr_d;
+        bram_write_data = write_data_d;
+      end
+    end
+
+    if (read_pending) begin
+        read_pending <= 0;
+        have_read    <= 1;
+        read_data_d  <= bram_read_data;
+    end else if (have_read) begin
+      `onwrite(read_data_r, read_data_a)
+        have_read <= 0;
+      end
+    end else begin
+      `onread(read_addr_r, read_addr_a)
+        // ======= Careful with the timing here! =====================
+        // We MUST capture bram_read_data on the very next clock since
+        // read_addr_d is free to change after the next clock
+        // ===========================================================
+        read_pending <= 1;
+      end
+    end
+
+  end
+
+endmodule
+
+
 == Constants ========================================================
 == TeX ==============================================================