ship: Dscratch == Ports =========================================================== data in: inReadAddr data out: outReadData data in: inWriteAddr data in: inWriteData token out: outWriteDone == Fleeterpreter ==================================================== private long[] mem = new long[0]; public long readMem(int addr) { return mem[addr]; } public void writeMem(int addr, long val) { if (addr >= mem.length) { long[] newmem = new long[addr * 2 + 1]; System.arraycopy(mem, 0, newmem, 0, mem.length); mem = newmem; } mem[addr] = val; } public void service() { if (box_inReadAddr.dataReadyForShip() && box_outReadData.readyForItemFromShip()) { box_outReadData.addDataFromShip((int)readMem(box_inReadAddr.removeDataForShip())); } if (box_inWriteAddr.dataReadyForShip() && box_inWriteData.dataReadyForShip() && box_outWriteDone.readyForItemFromShip()) { writeMem(box_inWriteAddr.removeDataForShip(), box_inWriteData.removeDataForShip()); box_outWriteDone.addTokenFromShip(); } } == FleetSim ============================================================== == 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 ============================================================== == Contributors ========================================================= Adam Megacz