X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ships%2FMemory.ship;h=2d1d6f15dbe6abc7fe5b7e02c51d47ebcdfdf943;hb=aee85d3dd0435554e14e03b97f268752843a441f;hp=cb36dd0d60957701af4de7151ecd94a729b71441;hpb=caa93dc7618f95e403b52ea834fa1f136d26e43d;p=fleet.git diff --git a/ships/Memory.ship b/ships/Memory.ship index cb36dd0..2d1d6f1 100644 --- a/ships/Memory.ship +++ b/ships/Memory.ship @@ -105,55 +105,28 @@ sequence guarantee problem mentioned in the previous paragraph. } mem[addr] = val; } - - private long stride = 0; - private long count = 0; - private long addr = 0; - private boolean writing = false; - private Queue toDispatch = new LinkedList(); + public void reset() { + super.reset(); + mem = new long[0]; + toDispatch.clear(); + } public void service() { - if (toDispatch.size() > 0) { - //if (!box_out.readyForDataFromShip()) return; - //box_out.addDataFromShip(toDispatch.remove()); - getInterpreter().dispatch(getInterpreter().readInstruction(toDispatch.remove(), getDock("out"))); + if (!box_out.readyForDataFromShip()) return; + box_out.addDataFromShip(toDispatch.remove()); } - - if (box_inCBD.dataReadyForShip() && box_out.readyForDataFromShip()) { + if (box_inCBD.dataReadyForShip()) { long val = box_inCBD.removeDataForShip(); - long addr = val >> 6; - long size = val & 0x3f; + long addr = ((Interpreter)getFleet()).CBD_OFFSET.getval(val); + long size = ((Interpreter)getFleet()).CBD_SIZE.getval(val); for(int i=0; i 0) { - if (writing) { - if (box_inDataWrite.dataReadyForShip() && box_out.readyForDataFromShip()) { - writeMem((int)addr, box_inDataWrite.removeDataForShip()); - box_out.addDataFromShip(0); - count--; - addr += stride; - } - } else { - if (box_out.readyForDataFromShip()) { - box_out.addDataFromShip(readMem((int)addr)); - count--; - addr += stride; - } - } - - } else if (box_inAddrRead.dataReadyForShip()) { - addr = box_inAddrRead.removeDataForShip(); - stride = 0; - count = 1; - writing = false; - - } else if (box_inAddrWrite.dataReadyForShip()) { - addr = box_inAddrWrite.removeDataForShip(); - stride = 0; - count = 1; - writing = true; + } else if (box_inAddrWrite.dataReadyForShip() && box_inDataWrite.dataReadyForShip() && box_out.readyForDataFromShip()) { + writeMem((int)box_inAddrWrite.removeDataForShip(), box_inDataWrite.removeDataForShip()); + box_out.addDataFromShip(0,true); + } else if (box_inAddrRead.dataReadyForShip() && box_out.readyForDataFromShip()) { + box_out.addDataFromShip(readMem((int)box_inAddrRead.removeDataForShip()),false); } } @@ -161,107 +134,112 @@ sequence guarantee problem mentioned in the previous paragraph. == FPGA ============================================================== - wire [(`DATAWIDTH-1):0] out1; - wire [(`DATAWIDTH-1):0] out2; + `define BRAM_ADDR_WIDTH 14 + `define BRAM_SIZE (1<<(`BRAM_ADDR_WIDTH)) - reg [(`CODEBAG_SIZE_BITS-1):0] counter; - reg [(`BRAM_ADDR_WIDTH-1):0] cursor; - initial cursor = 0; - initial counter = 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; - reg write_flag; - reg out_w; - reg dispatching_cbd; - initial write_flag = 0; - initial dispatching_cbd = 0; + reg out_w; + reg write_flag; + reg [(`BRAM_ADDR_WIDTH-1):0] cursor; + reg [(`CODEBAG_SIZE_BITS-1):0] counter; - wire [(`BRAM_ADDR_WIDTH-1):0] addr1; - assign addr1 = write_flag ? inAddrWrite_d[(`DATAWIDTH-1):0] : inAddrRead_d[(`DATAWIDTH-1):0]; - bram14 mybram(clk, rst, write_flag, addr1, cursor, inDataWrite_d, out1, out2); - - assign out_d_ = { out_w , (dispatching_cbd ? out2 : out1) }; + assign out_d_ = { out_w, out1 }; + // I use "blocking assignment" here in order to facilitate BRAM inference always @(posedge clk) begin + write_flag = 0; - write_flag <= 0; - - if (!rst) begin + 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[(`DATAWIDTH-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; - 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 ========================================================