123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- /*
- * memtest.v
- *
- * vim: ts=4 sw=4
- *
- * Copyright (C) 2020-2021 Sylvain Munaut <tnt@246tNt.com>
- * SPDX-License-Identifier: CERN-OHL-P-2.0
- */
- `default_nettype none
- module memtest #(
- parameter integer ADDR_WIDTH = 32,
- // auto
- parameter integer AL = ADDR_WIDTH - 1
- )(
- // Memory interface
- output wire [AL:0] mi_addr,
- output wire [ 6:0] mi_len,
- output wire mi_rw,
- output wire mi_valid,
- input wire mi_ready,
- output wire [31:0] mi_wdata,
- output wire [ 3:0] mi_wmsk,
- input wire mi_wack,
- input wire [31:0] mi_rdata,
- input wire mi_rstb,
- // Wishbone interface
- input wire [31:0] wb_wdata,
- output wire [31:0] wb_rdata,
- input wire [ 8:0] wb_addr,
- input wire wb_we,
- input wire wb_cyc,
- output wire wb_ack,
- // Clock / Reset
- input wire clk,
- input wire rst
- );
- // Signals
- // -------
- // Buffers
- wire [ 7:0] bw_waddr;
- wire [31:0] bw_wdata;
- wire bw_wren;
- reg [ 7:0] bw_raddr;
- wire [31:0] bw_rdata;
- wire bw_rden;
- reg [ 7:0] br_waddr;
- wire [31:0] br_wdata;
- wire br_wren;
- wire [ 7:0] br_raddr;
- wire [31:0] br_rdata;
- wire br_rden;
- // Wishbone
- reg wb_ack_i;
- reg wb_we_cmd;
- reg wb_we_addr;
- // Commands
- reg cmd_valid;
- reg cmd_start;
- reg cmd_read;
- reg [ 6:0] cmd_len;
- reg [AL:0] cmd_addr;
- reg cmd_dual;
- // Validate
- reg val_ok;
- // Buffers
- // -------
- ram_sdp #(
- .AWIDTH(8),
- .DWIDTH(32)
- ) buf_wr_I (
- .wr_addr (bw_waddr),
- .wr_data (bw_wdata),
- .wr_ena (bw_wren),
- .rd_addr (bw_raddr),
- .rd_data (bw_rdata),
- .rd_ena (bw_rden),
- .clk (clk)
- );
- ram_sdp #(
- .AWIDTH(8),
- .DWIDTH(32)
- ) buf_rd_I (
- .wr_addr (br_waddr),
- .wr_data (br_wdata),
- .wr_ena (br_wren),
- .rd_addr (br_raddr),
- .rd_data (br_rdata),
- .rd_ena (br_rden),
- .clk (clk)
- );
- // Wishbone interface
- // ------------------
- // Ack
- always @(posedge clk)
- wb_ack_i <= wb_cyc & ~wb_ack_i;
- assign wb_ack = wb_ack_i;
- // Read Mux
- assign wb_rdata = wb_ack_i ?
- (wb_addr[8] ? br_rdata : { 30'h00000000, val_ok, mi_ready }) :
- 32'h00000000;
- // Buffer accesses
- assign bw_waddr = wb_addr[7:0];
- assign bw_wdata = wb_wdata;
- assign bw_wren = wb_ack_i & wb_we & wb_addr[8];
- assign br_raddr = wb_addr[7:0];
- assign br_rden = 1'b1;
- // Write Strobes
- always @(posedge clk)
- if (wb_ack_i) begin
- wb_we_cmd <= 1'b0;
- wb_we_addr <= 1'b0;
- end else begin
- wb_we_cmd <= wb_cyc & wb_we & ~wb_addr[8] & ~wb_addr[0];
- wb_we_addr <= wb_cyc & wb_we & ~wb_addr[8] & wb_addr[0];
- end
- always @(posedge clk)
- cmd_start <= wb_we_cmd;
- always @(posedge clk)
- if (rst)
- cmd_valid <= 1'b0;
- else
- cmd_valid <= (cmd_valid & (~mi_ready | cmd_dual)) | cmd_start;
- always @(posedge clk)
- if (wb_we_cmd)
- cmd_dual <= wb_wdata[18];
- else if (mi_ready & mi_valid)
- cmd_dual <= 1'b0;
- always @(posedge clk)
- if (wb_we_cmd) begin
- cmd_read <= wb_wdata[ 16];
- cmd_len <= wb_wdata[ 6: 0];
- end
- always @(posedge clk)
- if (wb_we_addr)
- cmd_addr <= wb_wdata[ADDR_WIDTH-1:0];
- else if (mi_ready & mi_valid)
- cmd_addr <= cmd_addr + cmd_len + 1;
- // Memory interface
- // ----------------
- // Requests
- assign mi_addr = cmd_addr;
- assign mi_len = cmd_len;
- assign mi_rw = cmd_read;
- assign mi_valid = cmd_valid;
- // Write data (and read-validate)
- always @(posedge clk)
- if (wb_we_cmd)
- bw_raddr <= wb_wdata[15:8];
- else
- bw_raddr <= bw_raddr + bw_rden;
- assign mi_wdata = bw_rdata;
- assign mi_wmsk = 4'h0;
- assign bw_rden = (cmd_read ? mi_rstb : mi_wack) | cmd_start;
- // Read data
- assign br_wdata = mi_rdata;
- assign br_wren = mi_rstb;
- always @(posedge clk)
- if (wb_we_cmd)
- br_waddr <= wb_wdata[15:8];
- else
- br_waddr <= br_waddr + mi_rstb;
- // Data validation
- always @(posedge clk)
- if (wb_we_cmd)
- val_ok <= val_ok | wb_wdata[17];
- else
- val_ok <= val_ok & (~mi_rstb | (mi_rdata == bw_rdata));
- endmodule
|