module buffer ( clk, reset, vma, rd, wr, io, cpu_addr, cpu_data_in, buf_q, floppy_rdata, fill, dma, buflen ); input clk, reset; input vma, rd, wr, io; input [15:0] cpu_addr; input [7:0] cpu_data_in; input fill; input floppy_rdata; output [7:0] buf_q; output wire dma = (state != IDLE); input [7:0] buflen; parameter IDLE = 2'b00, FILLING = 2'b01, DONE = 2'b10; reg [1:0] state = IDLE; //parameter BUFLEN = 16'd255; reg [15:0] cntr; reg [1:0] stb_r; wire stbfront = (stb_r [1:0] == 2'b01); reg stbfront_r; always @(posedge clk or posedge reset) begin if (reset) begin state = IDLE; cntr [15:0] <= 16'b0; stb_r [1:0] <= 2'b0; end else begin // state = IDLE; stb_r [1:0] <= {stb_r [0], stb}; stbfront_r <= stbfront; case (state) IDLE: if (fill) state = FILLING; else state = IDLE; FILLING: begin if (stbfront_r) begin cntr [15:0] <= cntr [15:0] + 1'b1; if (cntr [7:0] == buflen [7:0]) state = DONE; end // else state = FILLING; end DONE: state = IDLE; default: state = IDLE; endcase end end // // Track buffer // wire bufsel = (cpu_addr [12]); // -------------------------- -- local access ---- ------ CPU access --------- wire bufclk = dma ? stb : clk & bufsel & vma & ~io; wire [15:0] bufaddr = dma ? cntr [15:0] : cpu_addr [15:0]; wire [7:0] bufdata = dma ? mfm_data [7:0] : cpu_data_in [7:0]; wire bufwren = dma ? 1'b1 : wr & bufsel & vma & ~io; trackbuf trackbuf_i ( .clock (bufclk), .address (bufaddr [15:0]), .data (bufdata [7:0]), .q (buf_q [7:0]), .wren (bufwren) ); // // MFM bit flow deserializer // wire [7:0] mfm_data; wire stb; mfm mfm_i ( .clk (clk), .reset (reset), .bitflow (floppy_rdata), .data_o (mfm_data [7:0]), .stb (stb), ); endmodule