Browse Source

cores: Replace local 'mem_cache' with 'no2memcache' submodule

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Sylvain Munaut 3 năm trước cách đây
mục cha
commit
aa7e48dd21

+ 3 - 0
.gitmodules

@@ -19,3 +19,6 @@
 [submodule "cores/no2qpimem"]
 	path = cores/no2qpimem
 	url = https://github.com/no2fpga/no2qpimem.git
+[submodule "cores/no2memcache"]
+	path = cores/no2memcache
+	url = https://github.com/no2fpga/no2memcache.git

+ 0 - 4
cores/mem_cache/Makefile

@@ -1,4 +0,0 @@
-CORE := mem_cache
-
-NO2BUILD_DIR ?= $(abspath ../../build)
-include $(NO2BUILD_DIR)/core-rules.mk

+ 0 - 23
cores/mem_cache/no2core.mk

@@ -1,23 +0,0 @@
-CORE := mem_cache
-
-DEPS_mem_cache := no2misc no2ice40
-
-RTL_SRCS_mem_cache := $(addprefix rtl/, \
-	mc_bus_vex.v \
-	mc_bus_wb.v \
-	mc_core.v \
-	mc_tag_match.v \
-	mc_tag_ram.v \
-)
-
-SIM_SRCS_mem_cache := $(addprefix sim/, \
-	mem_sim.v \
-)
-
-TESTBENCHES_mem_cache := \
-	mc_core_tb \
-	mc_wb_tb \
-	mem_sim_tb \
-	$(NULL)
-
-include $(NO2BUILD_DIR)/core-magic.mk

+ 0 - 328
cores/mem_cache/rtl/mc_bus_vex.v

@@ -1,328 +0,0 @@
-/*
- * mc_bus_vex.v
- *
- * vim: ts=4 sw=4
- *
- * Copyright (C) 2020  Sylvain Munaut <tnt@246tNt.com>
- * All rights reserved.
- *
- * BSD 3-clause, see LICENSE.bsd
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-`default_nettype none
-
-module mc_bus_vex #(
-	parameter integer WB_N = 2,
-
-	// auto
-	parameter integer CL = WB_N - 1,
-	parameter integer DL = (32*WB_N)- 1
-)(
-	// VexRiscv busses
-	input  wire        i_axi_ar_valid,
-	output wire        i_axi_ar_ready,
-	input  wire [31:0] i_axi_ar_payload_addr,
-	input  wire [ 7:0] i_axi_ar_payload_len,	// ignored, assumes 8'h07
-	input  wire [ 1:0] i_axi_ar_payload_burst,	// ignored
-	input  wire [ 3:0] i_axi_ar_payload_cache,	// ignored
-	input  wire [ 2:0] i_axi_ar_payload_prot,	// ignored
-	output wire        i_axi_r_valid,
-	input  wire        i_axi_r_ready,			// ignored, assumes 1'b1
-	output wire [31:0] i_axi_r_payload_data,
-	output wire [ 1:0] i_axi_r_payload_resp,
-	output wire        i_axi_r_payload_last,	// Fixed to zero
-
-	input  wire        d_wb_cyc,
-	input  wire        d_wb_stb,
-	output reg         d_wb_ack,
-	input  wire        d_wb_we,
-	input  wire [29:0] d_wb_adr,
-	output wire [31:0] d_wb_dat_miso,
-	input  wire [31:0] d_wb_dat_mosi,
-	input  wire [ 3:0] d_wb_sel,
-	output wire        d_wb_err,
-	input  wire [ 1:0] d_wb_bte,
-	input  wire [ 2:0] d_wb_cti,
-
-	// Peripheral wishbone bus (0x8000_0000 -> 0x8fff_ffff)
-	output wire [21:0] wb_addr,
-	output wire [31:0] wb_wdata,
-	output wire [ 3:0] wb_wmsk,
-	input  wire [DL:0] wb_rdata,
-	output reg  [CL:0] wb_cyc,
-	output wire        wb_we,
-	input  wire [CL:0] wb_ack,
-
-	// RAM (0x0000_0000 - 0x3fff_ffff)
-	output wire [27:0] ram_addr,
-	output wire [31:0] ram_wdata,
-	output wire [ 3:0] ram_wmsk,
-	input  wire [31:0] ram_rdata,
-	output wire        ram_we,
-
-	// Cache (0x4000_0000 - 0x7fff_0000)
-		// Request output
-	output wire [27:0] req_addr_pre,	// 1 cycle early
-
-	output wire        req_valid,
-
-	output wire        req_write,
-	output wire [31:0] req_wdata,
-	output wire [ 3:0] req_wmsk,
-
-		// Response input
-	input  wire        resp_ack,
-	input  wire        resp_nak,
-	input  wire [31:0] resp_rdata,
-
-	// Common
-	input  wire clk,
-	input  wire rst
-);
-
-	// Signals
-	// -------
-
-	// Global control
-	localparam
-		ST_IDLE     = 0,
-		ST_D_CACHE  = 1,
-		ST_D_RAM    = 2,
-		ST_D_IO     = 3,
-		ST_I_PROBE  = 4,
-		ST_I_ACTIVE = 5,
-		ST_I_FLUSH  = 6;
-
-	reg  [ 2:0] state;
-	reg  [ 2:0] state_nxt;
-
-	reg  ctrl_is_ibus;
-	reg  ctrl_is_dbus;
-	reg  ctrl_is_cache;
-	reg  ctrl_is_ram;
-	reg  ctrl_is_io;
-
-	// Data path
-	reg  [31:0] rdata_io;
-	wire [31:0] rdata_mux_i;
-	wire [31:0] rdata_mux_d;
-	wire [ 1:0] rdata_sel;
-
-	// Address path
-	wire [29:0] addr_mux;
-	wire        addr_sel;
-
-	// Instruction bus
-	reg  [2:0] ib_addr_cnt;
-	wire [2:0] ib_addr_lsb;
-	wire       ib_addr_last;
-
-	// Cache access
-	reg req_new;
-
-	// Peripheral access
-	wire wb_cyc_i;
-	reg  wb_ack_i;
-
-
-	// Global control
-	// --------------
-
-	// State reg
-	always @(posedge clk)
-		if (rst)
-			state <= ST_IDLE;
-		else
-			state <= state_nxt;
-
-	// Next-state
-	always @(*)
-	begin
-		// Default
-		state_nxt = state;
-
-		// State transitions
-		case (state)
-			ST_IDLE:
-				if (i_axi_ar_valid)
-					state_nxt = i_axi_ar_payload_addr[30] ? ST_I_PROBE : ST_I_ACTIVE;
-				else if (d_wb_cyc)
-					state_nxt = d_wb_adr[29] ? ST_D_IO : (d_wb_adr[28] ? ST_D_CACHE : ST_D_RAM);
-
-			ST_I_PROBE:
-				if (resp_ack)
-					state_nxt = ST_I_ACTIVE;
-
-			ST_I_ACTIVE:
-				if (ib_addr_last)
-					state_nxt = ctrl_is_cache ? ST_I_FLUSH : ST_IDLE;
-
-			ST_I_FLUSH:
-				state_nxt = ST_IDLE;
-
-			ST_D_CACHE:
-				if (resp_ack)
-					state_nxt = ST_IDLE;
-
-			ST_D_RAM:
-				state_nxt = ST_IDLE;
-
-			ST_D_IO:
-				if (wb_ack_i)
-					state_nxt = ST_IDLE;
-		endcase
-	end
-
-	// Some status
-	always @(posedge clk)
-	begin
-		if (state == ST_IDLE) begin
-			ctrl_is_ibus <=  i_axi_ar_valid;
-			ctrl_is_dbus <= ~i_axi_ar_valid & d_wb_cyc;
-			ctrl_is_cache = i_axi_ar_valid ?  i_axi_ar_payload_addr[30] : (d_wb_adr[29:28] == 2'b01);
-			ctrl_is_ram   = i_axi_ar_valid ? ~i_axi_ar_payload_addr[30] : (d_wb_adr[29:28] == 2'b00);
-			ctrl_is_io    = i_axi_ar_valid ? 1'b0 : d_wb_adr[29];
-		end
-	end
-
-	// Read Data mux sel
-	assign rdata_sel[1] = ctrl_is_io;
-	assign rdata_sel[0] = ctrl_is_ram;
-
-	// Address mux sel
-	assign addr_sel = (state == ST_IDLE) ? ~i_axi_ar_valid : ctrl_is_dbus;
-
-
-	// Data path
-	// ---------
-
-	// OR all data from IO
-	always @(posedge clk)
-	begin : rdata
-		integer i;
-		rdata_io = 32'h00000000;
-		for (i=0; i<WB_N; i=i+1)
-			rdata_io = rdata_io | wb_rdata[32*i+:32];
-	end
-
-	// Read muxes for IBus / DBus
-	assign rdata_mux_i = rdata_sel[0] ? ram_rdata : resp_rdata;
-	assign rdata_mux_d = rdata_sel[1] ? rdata_io  : rdata_mux_i;
-
-
-	// Address path
-	// ------------
-
-	assign addr_mux = addr_sel ? d_wb_adr : { i_axi_ar_payload_addr[31:5], ib_addr_lsb };
-
-
-	// Instruction Bus
-	// ---------------
-
-	// Address counter
-	always @(posedge clk)
-		ib_addr_cnt <= ib_addr_lsb;
-
-	assign ib_addr_lsb = (state == ST_IDLE) ? 3'b000 : (ib_addr_cnt + (resp_ack | (state == ST_I_ACTIVE)));
-	assign ib_addr_last = (ib_addr_cnt == 3'b111);
-
-	assign i_axi_ar_ready = ctrl_is_cache ? (state == ST_I_FLUSH) : ib_addr_last;
-
-	// Data channel
-	assign i_axi_r_valid = (ctrl_is_ibus & ctrl_is_cache) ? resp_ack : (state == ST_I_ACTIVE);
-
-	assign i_axi_r_payload_data = rdata_mux_i;
-
-	assign i_axi_r_payload_resp = 2'b00;	// No errors
-	assign i_axi_r_payload_last = 1'b0;		// Not used by Vex
-
-
-	// Data Bus
-	// --------
-
-	always @(*)
-	begin
-		d_wb_ack = 0;
-
-		case (state)
-			ST_D_CACHE:
-				d_wb_ack = resp_ack;
-			ST_D_RAM:
-				d_wb_ack = 1'b1;
-			ST_D_IO:
-				d_wb_ack = wb_ack_i;
-		endcase
-	end
-
-	assign d_wb_dat_miso = rdata_mux_d;
-	assign d_wb_err = 1'b0;					// No errors
-
-
-	// Cache access
-	// ------------
-
-	assign req_addr_pre =  addr_mux[27:0];
-	assign req_valid    =  req_new | resp_nak | ((state == ST_I_ACTIVE) & ctrl_is_cache);
-	assign req_write    =  d_wb_we & (state == ST_D_CACHE);
-	assign req_wdata    =  d_wb_dat_mosi;
-	assign req_wmsk     = ~d_wb_sel;
-
-	always @(posedge clk)
-		req_new <= (state == ST_IDLE) && ((state_nxt == ST_I_PROBE) || (state_nxt == ST_D_CACHE));
-
-
-	// RAM access
-	// ----------
-
-	assign ram_addr  =  addr_mux[27:0];
-	assign ram_wdata =  d_wb_dat_mosi;
-	assign ram_wmsk  = ~d_wb_sel;
-	assign ram_we    =  d_wb_we & (state == ST_D_RAM);
-
-
-	// Peripheral access
-	// -----------------
-
-	assign wb_addr  =  d_wb_adr[21:0];
-	assign wb_wdata =  d_wb_dat_mosi;
-	assign wb_wmsk  = ~d_wb_sel;
-	assign wb_we    =  d_wb_we;
-
-	assign wb_cyc_i = (state == ST_IDLE) && (state_nxt == ST_D_IO);
-
-	always @(posedge clk)
-		wb_ack_i <= |wb_ack;
-
-	always @(posedge clk)
-	begin : wb_cyc_proc
-		integer i;
-		if (rst)
-			wb_cyc <= 0;
-		else
-			for (i=0; i<WB_N; i=i+1)
-				wb_cyc[i] <= (wb_cyc[i] & ~wb_ack[i]) | (wb_cyc_i & (d_wb_adr[25:22] == i));
-	end
-
-endmodule

+ 0 - 95
cores/mem_cache/rtl/mc_bus_wb.v

@@ -1,95 +0,0 @@
-/*
- * mc_bus_wb.v
- *
- * vim: ts=4 sw=4
- *
- * Copyright (C) 2020  Sylvain Munaut <tnt@246tNt.com>
- * All rights reserved.
- *
- * BSD 3-clause, see LICENSE.bsd
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-`default_nettype none
-
-module mc_bus_wb #(
-	parameter integer ADDR_WIDTH = 24,
-
-	// auto
-	parameter integer BL = ADDR_WIDTH - 1
-)(
-	// Wishbone bus
-	input  wire [BL:0] wb_addr,
-	input  wire [31:0] wb_wdata,
-	input  wire [ 3:0] wb_wmsk,
-	output wire [31:0] wb_rdata,
-	input  wire        wb_cyc,
-	input  wire        wb_we,
-	output wire        wb_ack,
-
-	// Request output
-	output wire [BL:0] req_addr_pre,	// 1 cycle early
-
-	output wire        req_valid,
-
-	output wire        req_write,
-	output wire [31:0] req_wdata,
-	output wire [ 3:0] req_wmsk,
-
-	// Response input
-	input  wire        resp_ack,
-	input  wire        resp_nak,
-	input  wire [31:0] resp_rdata,
-
-	// Common
-	input  wire clk,
-	input  wire rst
-);
-	// Control path
-	reg pending;
-	reg new;
-
-	always @(posedge clk or posedge rst)
-		if (rst)
-			pending <= 1'b0;
-		else
-			pending <= (pending | wb_cyc) & ~resp_ack;
-
-	always @(posedge clk)
-		new <= wb_cyc & ~pending;
-
-	assign req_addr_pre = wb_addr;
-	assign req_valid = resp_nak | new;
-
-	assign wb_ack = resp_ack;
-
-	// Write path
-	assign req_write = wb_we;
-	assign req_wdata = wb_wdata;
-	assign req_wmsk  = wb_wmsk;
-
-	// Read path
-	assign wb_rdata  = resp_rdata;
-
-endmodule

+ 0 - 536
cores/mem_cache/rtl/mc_core.v

@@ -1,536 +0,0 @@
-/*
- * mc_core.v
- *
- * vim: ts=4 sw=4
- *
- * Copyright (C) 2020  Sylvain Munaut <tnt@246tNt.com>
- * All rights reserved.
- *
- * BSD 3-clause, see LICENSE.bsd
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-`default_nettype none
-
-module mc_core #(
-	parameter integer N_WAYS     =  4,
-	parameter integer ADDR_WIDTH = 24,	/* Word address, 64 Mbytes */
-	parameter integer CACHE_LINE = 64,
-	parameter integer CACHE_SIZE = 64,	/* 64k or 128k */
-
-	// auto
-	parameter integer BL = ADDR_WIDTH - 1
-)(
-	// Request input
-	input  wire [BL:0] req_addr_pre,	// 1 cycle early
-
-	input  wire        req_valid,
-
-	input  wire        req_write,
-	input  wire [31:0] req_wdata,
-	input  wire [ 3:0] req_wmsk,
-
-	// Response output (1 cycle later)
-	output reg         resp_ack,
-	output reg         resp_nak,
-	output wire [31:0] resp_rdata,
-
-	// Memory controller interface
-	output wire [BL: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,
-	input  wire        mi_wack,
-	input  wire        mi_wlast,
-
-	input  wire [31:0] mi_rdata,
-	input  wire        mi_rstb,
-	input  wire        mi_rlast,
-
-	// Common
-	input  wire clk,
-	input  wire rst
-);
-
-	genvar i;
-
-	// Constants
-	// ---------
-
-	localparam integer SPRAM_ADDR_WIDTH = (CACHE_SIZE == 128) ? 15 : 14;
-	localparam integer SL = SPRAM_ADDR_WIDTH - 1;
-
-	localparam integer OFS_WIDTH = $clog2(CACHE_LINE) - 2;
-	localparam integer IDX_WIDTH = SPRAM_ADDR_WIDTH - $clog2(N_WAYS) - OFS_WIDTH;
-	localparam integer TAG_WIDTH = ADDR_WIDTH - (IDX_WIDTH + OFS_WIDTH);
-	localparam integer AGE_WIDTH = $clog2(N_WAYS);
-	localparam integer WAY_WIDTH = $clog2(N_WAYS);
-
-	localparam integer OL = OFS_WIDTH - 1;
-	localparam integer IL = IDX_WIDTH - 1;
-	localparam integer TL = TAG_WIDTH - 1;
-	localparam integer AL = AGE_WIDTH - 1;
-	localparam integer WL = WAY_WIDTH - 1;
-
-	initial begin
-		$display("Memory cache config :");
-		$display(" - %d ways", N_WAYS);
-		$display(" - %d kbytes cache", CACHE_SIZE);
-		$display(" - %d bytes cache lines", CACHE_LINE);
-		$display(" - %d Mbytes address space", 1 << (ADDR_WIDTH - 18));
-		$display(" - %d/%d/%d address split", TAG_WIDTH, IDX_WIDTH, OFS_WIDTH);
-	end
-
-
-	localparam [1:0]
-		ST_BUS_MODE = 0,
-		ST_MEMIF_ISSUE_WRITE = 1,
-		ST_MEMIF_ISSUE_READ = 2,
-		ST_MEMIF_WAIT = 3;
-
-
-	// Signals
-	// -------
-
-	// Control
-	reg  [1:0]  ctrl_state;
-	reg  [1:0]  ctrl_state_nxt;
-
-	wire        ctrl_bus_mode;
-	wire        ctrl_tagram_we;
-
-	// Offset counter
-	reg  [OL:0] cnt_ofs;
-	wire        cnt_ofs_rst;
-	wire        cnt_ofs_inc;
-
-	// Requests
-	wire [IL:0] req_addr_pre_idx;
-
-	reg  [BL:0] req_addr;
-	wire [TL:0] req_addr_tag;
-	wire [IL:0] req_addr_idx;
-	wire [OL:0] req_addr_ofs;
-
-	// Tag Memory
-	wire        way_valid[0:N_WAYS-1];
-	wire        way_dirty[0:N_WAYS-1];
-	wire [AL:0] way_age[0:N_WAYS-1];
-	wire [TL:0] way_tag[0:N_WAYS-1];
-
-	reg         way_valid_nxt[0:N_WAYS-1];
-	reg         way_valid_we[0:N_WAYS-1];
-
-	reg         way_dirty_nxt[0:N_WAYS-1];
-	reg         way_dirty_we[0:N_WAYS-1];
-
-	reg  [AL:0] way_age_nxt[0:N_WAYS-1];
-	wire        way_age_we;
-
-	wire [TL:0] way_tag_nxt;
-	reg         way_tag_we[0:N_WAYS-1];
-
-	// Pre-compute on tag mem data
-	wire [N_WAYS-1:0] way_match;	// Needs to be vector to use unary OR
-	wire [AL:0] way_match_age[0:N_WAYS-1];
-
-	// Lookup
-	wire        lu_miss;
-	wire        lu_hit;
-	reg  [WL:0] lu_hit_way;
-	reg  [AL:0] lu_hit_age;
-
-	// Eviction
-	reg  [WL:0] ev_way;
-	wire        ev_valid;
-	wire        ev_dirty;
-	wire [TL:0] ev_tag;
-
-	reg  [WL:0] ev_way_r;
-	reg         ev_valid_r;
-	reg  [TL:0] ev_tag_r;
-
-	// Data memory
-	reg  [SL:0] dm_addr;
-	wire [31:0] dm_rdata;
-	reg         dm_re;
-	reg  [31:0] dm_wdata;
-	wire [ 7:0] dm_wmsk_nibble;
-	reg  [ 3:0] dm_wmsk;
-	reg         dm_we;
-
-
-	// Control
-	// -------
-
-	// FSM state register
-	always @(posedge clk or posedge rst)
-		if (rst)
-			ctrl_state <= ST_BUS_MODE;
-		else
-			ctrl_state <= ctrl_state_nxt;
-
-	// FSM next-state logic
-	always @(*)
-	begin
-		// Default is not to move
-		ctrl_state_nxt = ctrl_state;
-
-		// State change logic
-		case (ctrl_state)
-			ST_BUS_MODE:
-				if (lu_miss)
-					ctrl_state_nxt = ev_dirty ? ST_MEMIF_ISSUE_WRITE : ST_MEMIF_ISSUE_READ;
-
-			ST_MEMIF_ISSUE_WRITE:
-				if (mi_ready)
-					ctrl_state_nxt = ST_MEMIF_ISSUE_READ;
-
-			ST_MEMIF_ISSUE_READ:
-				if (mi_ready)
-					ctrl_state_nxt = ST_MEMIF_WAIT;
-
-			ST_MEMIF_WAIT:
-				if (mi_rstb && mi_rlast)
-					ctrl_state_nxt = ST_BUS_MODE;
-		endcase
-	end
-
-	// State conditions
-	assign ctrl_bus_mode = ctrl_state == ST_BUS_MODE;
-
-
-	// Memory interface
-	// ----------------
-
-	// Issue commands
-	assign mi_addr  = {
-		(ctrl_state == ST_MEMIF_ISSUE_WRITE) ? ev_tag_r : req_addr_tag,
-		req_addr_idx,
-		{OFS_WIDTH{1'b0}}
-	};
-	assign mi_len   = (CACHE_LINE / 4) - 1;
-	assign mi_rw    = (ctrl_state == ST_MEMIF_ISSUE_READ);
-	assign mi_valid = (ctrl_state == ST_MEMIF_ISSUE_WRITE) || (ctrl_state == ST_MEMIF_ISSUE_READ);
-
-	// Read data path
-	assign mi_wdata = dm_rdata;
-
-	// Offset counter
-	always @(posedge clk)
-		if (cnt_ofs_rst)
-			cnt_ofs <= 0;
-		else if (cnt_ofs_inc)
-			cnt_ofs <= cnt_ofs + 1;
-
-	assign cnt_ofs_rst = ctrl_bus_mode | (mi_wack & mi_wlast);
-	assign cnt_ofs_inc = mi_rstb | mi_wack | (mi_ready & (ctrl_state == ST_MEMIF_ISSUE_WRITE));
-
-
-	// Request
-	// -------
-
-	// Extract index from pre-address for tag memory lookup
-	assign req_addr_pre_idx = req_addr_pre[IDX_WIDTH+OFS_WIDTH-1:OFS_WIDTH];
-
-	// Register the pre-address, _only_ if in bus mode for next cycle
-	always @(posedge clk)
-		if (ctrl_state_nxt == ST_BUS_MODE)
-			req_addr <= req_addr_pre;
-
-	// Split address
-	assign { req_addr_tag, req_addr_idx, req_addr_ofs } = req_addr;
-
-
-	// Tag Memory
-	// ----------
-
-	// Blocks
-	generate
-		for (i=0; i<N_WAYS; i=i+1)
-			mc_tag_ram #(
-				.IDX_WIDTH(IDX_WIDTH),
-				.TAG_WIDTH(TAG_WIDTH),
-				.AGE_WIDTH(AGE_WIDTH)
-			) tag_ram_I (
-				.w_idx     (req_addr_idx),
-				.w_ena     (ctrl_tagram_we),
-				.w_valid_we(way_valid_we[i]),
-				.w_valid   (way_valid_nxt[i]),
-				.w_dirty_we(way_dirty_we[i]),
-				.w_dirty   (way_dirty_nxt[i]),
-				.w_age_we  (way_age_we),
-				.w_age     (way_age_nxt[i]),
-				.w_tag_we  (way_tag_we[i]),
-				.w_tag     (way_tag_nxt),
-				.r_ena     (ctrl_state_nxt == ST_BUS_MODE),
-				.r_idx     (req_addr_pre_idx),
-				.r_valid   (way_valid[i]),
-				.r_dirty   (way_dirty[i]),
-				.r_age     (way_age[i]),
-				.r_tag     (way_tag[i]),
-				.clk       (clk)
-			);
-	endgenerate
-
-
-	// Lookup logic
-	// ------------
-
-	// Per-way precompute
-	generate
-		for (i=0; i<N_WAYS; i=i+1)
-		begin
-//`define GENERIC
-`ifdef GENERIC
-			assign way_match[i] = way_valid[i] & (way_tag[i] == req_addr_tag);
-`else
-			// Comparator
-			mc_tag_match #(
-				.TAG_WIDTH(TAG_WIDTH)
-			) tag_match_I (
-				.ref(req_addr_tag),
-				.tag(way_tag[i]),
-				.valid(way_valid[i]),
-				.match(way_match[i])
-			);
-`endif
-
-			// Age
-			assign way_match_age[i] = way_match[i] ? way_age[i] : 2'b00;
-		end
-	endgenerate
-
-	// Hit / Miss
-	assign lu_miss = ctrl_bus_mode & req_valid & ~|way_match;
-	assign lu_hit  = ctrl_bus_mode & req_valid &  |way_match;
-
-	// Hit way and age
-	always @(*)
-	begin : hit
-		integer w;
-
-		// Any way that's a match (should be only one !)
-		lu_hit_way = 0;
-		for (w=1; w<N_WAYS; w=w+1)
-			if (way_match[w])
-				lu_hit_way = w;
-
-		// Or all the pre-masked values
-		lu_hit_age = 0;
-		for (w=0; w<N_WAYS; w=w+1)
-			lu_hit_age = lu_hit_age | way_match_age[w];
-	end
-
-
-	// Eviction logic
-	// --------------
-
-	// Select way to evict
-	always @(*)
-	begin : evict
-		integer w;
-
-		// Find a way that's either invalid or "oldest"
-		ev_way = 0;
-		for (w=1; w<N_WAYS; w=w+1)
-			if (!way_valid[w] || (way_age[w] == (N_WAYS-1)))
-				ev_way = w;
-	end
-
-	// Muxes for tag and dirty flags
-	assign ev_valid = way_valid[ev_way];
-	assign ev_dirty = way_dirty[ev_way];
-	assign ev_tag   = way_tag[ev_way];
-
-	// Save them for mem mode
-	always @(posedge clk)
-	begin
-		if (ctrl_bus_mode) begin
-			ev_way_r   <= ev_way;
-			ev_valid_r <= ev_valid;
-			ev_tag_r   <= ev_tag;
-		end
-	end
-
-
-	// Tag Memory update logic
-	// -----------------------
-
-	// Global write enable
-	assign ctrl_tagram_we = lu_hit | ((ctrl_state == ST_MEMIF_ISSUE_READ) & mi_ready);
-
-	// Flag update
-	always @(*)
-	begin : dirty_next
-		integer w;
-
-		if (ctrl_bus_mode)
-			// Bus Mode
-			for (w=0; w<N_WAYS; w=w+1) begin
-				// Valid
-				way_valid_nxt[w] = 1'b0;
-				way_valid_we[w]  = 1'b0;
-
-				// Dirty: Set on write
-				way_dirty_nxt[w] = 1'b1;
-				way_dirty_we[w]  = req_valid & req_write & way_match[w];
-			end
-
-		else
-			// Cache line load
-			for (w=0; w<N_WAYS; w=w+1) begin
-				// Valid
-				way_valid_nxt[w] = 1'b1;
-				way_valid_we[w]  = (w == ev_way_r);
-
-				// Dirty: Set on write
-				way_dirty_nxt[w] = 1'b0;
-				way_dirty_we[w]  = (w == ev_way_r);
-			end
-	end
-
-	// Age update (on hit)
-	assign way_age_we = 1'b1; // ctrl_bus_mode;
-
-	always @(*)
-	begin : age_next
-		integer w;
-
-		if (ctrl_bus_mode)
-		begin
-			// Next age is 0 for the hit, max for invalid and increment if current
-			// age is lower than the age of the hit way
-			for (w=0; w<N_WAYS; w=w+1)
-				if (!way_valid[w])
-					way_age_nxt[w] = N_WAYS - 1;
-				else if (way_match[w])
-					way_age_nxt[w] = 0;
-				else if (way_age[w] < lu_hit_age)
-					way_age_nxt[w] = way_age[w] + 1;
-				else
-					way_age_nxt[w] = way_age[w];
-		end else begin
-			for (w=0; w<N_WAYS; w=w+1)
-				if (!way_valid[w])
-					way_age_nxt[w] = N_WAYS - 1;
-				else if (w == ev_way_r)
-					way_age_nxt[w] = 0;
-				else
-					way_age_nxt[w] = way_age[w] + ev_valid_r;
-		end
-
-/*
-		// Next age is 0 for the hit, max for invalid and increment if current
-		// age is lower than the age of the hit way
-		for (w=0; w<N_WAYS; w=w+1)
-			if (!way_valid[w])
-				way_age_nxt[w] = N_WAYS - 1;
-			else if (way_match[w])
-				way_age_nxt[w] = 0;
-			else if (way_age[w] < lu_hit_age)
-				way_age_nxt[w] = way_age[w] + 1;
-			else
-				way_age_nxt[w] = way_age[w];
-*/
-	end
-
-	// Tag update
-	assign way_tag_nxt = req_addr_tag;
-
-	always @(*)
-	begin : tag_next
-		integer w;
-
-		for (w=0; w<N_WAYS; w=w+1)
-			way_tag_we[w] = (ctrl_state == ST_MEMIF_ISSUE_READ) && (w == ev_way_r);
-	end
-
-
-	// Data Memory
-	// -----------
-
-	// Mem-block
-	ice40_spram_gen #(
-		.ADDR_WIDTH(SPRAM_ADDR_WIDTH),
-		.DATA_WIDTH(32)
-	) data_ram_I (
-		.addr(dm_addr),
-		.rd_data(dm_rdata),
-		.rd_ena(dm_re),
-		.wr_data(dm_wdata),
-		.wr_mask(dm_wmsk_nibble),
-		.wr_ena(dm_we),
-		.clk(clk)
-	);
-
-	// Extend mask to nibbles
-	assign dm_wmsk_nibble = {
-		dm_wmsk[3], dm_wmsk[3],
-		dm_wmsk[2], dm_wmsk[2],
-		dm_wmsk[1], dm_wmsk[1],
-		dm_wmsk[0], dm_wmsk[0]
-	};
-
-	// Muxing
-	always @(*)
-	begin
-		if (ctrl_bus_mode) begin
-			// Bus Access
-			dm_addr  = { lu_hit_way, req_addr_idx, req_addr_ofs };
-			dm_re    = 1'b1;
-			dm_wdata = req_wdata;
-			dm_wmsk  = req_wmsk;
-			dm_we    = req_write & lu_hit;
-		end else begin
-			// Read or Write access to/from memory interface
-			dm_addr  = { ev_way_r, req_addr_idx, cnt_ofs };
-			dm_re    = cnt_ofs_inc;
-			dm_wdata = mi_rdata;
-			dm_wmsk  = 4'h0;
-			dm_we    = mi_rstb;
-		end
-	end
-
-
-	// Responses
-	// ---------
-
-	// Data is direct from the data memory
-	assign resp_rdata = dm_rdata;
-
-	// ACK / NAK
-	always @(posedge clk or posedge rst)
-		if (rst) begin
-			resp_ack <= 1'b0;
-			resp_nak <= 1'b0;
-		end else begin
-			resp_ack <= lu_hit;
-			resp_nak <= lu_miss | (req_valid & ~ctrl_bus_mode);
-		end
-
-endmodule

+ 0 - 112
cores/mem_cache/rtl/mc_tag_match.v

@@ -1,112 +0,0 @@
-/*
- * mc_tag_match.v
- *
- * vim: ts=4 sw=4
- *
- * Copyright (C) 2020  Sylvain Munaut <tnt@246tNt.com>
- * All rights reserved.
- *
- * BSD 3-clause, see LICENSE.bsd
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-`default_nettype none
-
-module mc_tag_match #(
-	parameter integer TAG_WIDTH = 12
-)(
-	input  wire [TAG_WIDTH-1:0] ref,
-	input  wire [TAG_WIDTH-1:0] tag,
-	input  wire valid,
-	output wire match
-);
-
-	genvar i;
-
-	// Constants
-	// ---------
-
-	localparam integer CW = (TAG_WIDTH + 1) / 2;
-	localparam integer AW = ((CW + 1)  + 3) / 4;
-
-
-	// Signals
-	// -------
-
-	wire [(2*CW)-1:0] cmp_in0;
-	wire [(2*CW)-1:0] cmp_in1;
-	wire [   CW -1:0] cmp_out;
-
-	wire [(4*AW)-1:0] agg_in;
-	wire [   AW -1:0] agg_out;
-
-
-	// Comparator stage
-	// ----------------
-
-	// Map input to even number, pad with 0
-	assign cmp_in0 = { {(TAG_WIDTH & 1){1'b0}}, ref };
-	assign cmp_in1 = { {(TAG_WIDTH & 1){1'b0}}, tag };
-
-	// Comparator, 2 bits at a time
-	generate
-		for (i=0; i<CW; i=i+1)
-			SB_LUT4 #(
-				.LUT_INIT(16'h9009)
-			) lut_cmp_I (
-				.I0(cmp_in0[2*i+0]),
-				.I1(cmp_in1[2*i+0]),
-				.I2(cmp_in0[2*i+1]),
-				.I3(cmp_in1[2*i+1]),
-				.O(cmp_out[i])
-			);
-	endgenerate
-
-
-	// Aggregation stage
-	// -----------------
-
-	// Map aggregator input
-	assign agg_in = { {((4*AW)-CW-1){1'b1}}, valid, cmp_out };
-
-	// Aggregate 4 bits at a time
-	generate
-		for (i=0; i<AW; i=i+1)
-			SB_LUT4 #(
-				.LUT_INIT(16'h8000)
-			) lut_cmp_I (
-				.I0(agg_in[4*i+3]),
-				.I1(agg_in[4*i+2]),
-				.I2(agg_in[4*i+1]),
-				.I3(agg_in[4*i+0]),
-				.O(agg_out[i])
-			);
-	endgenerate
-
-	// Final OR
-		// This is not manually done because we want the optimizer to merge it
-		// with other logic
-	assign match = &agg_out;
-
-endmodule

+ 0 - 165
cores/mem_cache/rtl/mc_tag_ram.v

@@ -1,165 +0,0 @@
-/*
- * mc_tag_ram.v
- *
- * vim: ts=4 sw=4
- *
- * Copyright (C) 2020  Sylvain Munaut <tnt@246tNt.com>
- * All rights reserved.
- *
- * BSD 3-clause, see LICENSE.bsd
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-`default_nettype none
-
-module mc_tag_ram #(
-	parameter integer IDX_WIDTH =  8,
-	parameter integer TAG_WIDTH = 12,
-	parameter integer AGE_WIDTH =  2,
-
-	// auto
-	parameter integer IL = IDX_WIDTH-1,
-	parameter integer TL = TAG_WIDTH-1,
-	parameter integer AL = AGE_WIDTH-1
-)(
-	// Write
-	input  wire [IL:0] w_idx,
-	input  wire        w_ena,
-
-	input  wire        w_valid_we,
-	input  wire        w_valid,
-
-	input  wire        w_dirty_we,
-	input  wire        w_dirty,
-
-	input  wire        w_age_we,
-	input  wire [AL:0] w_age,
-
-	input  wire        w_tag_we,
-	input  wire [TL:0] w_tag,
-
-	// Read
-	input  wire [IL:0] r_idx,
-	input  wire        r_ena,
-
-	output wire        r_valid,
-	output wire        r_dirty,
-	output wire [AL:0] r_age,
-	output wire [TL:0] r_tag,
-
-	// Common
-	input  wire        clk
-);
-
-	// Configuration
-	// -------------
-
-	initial
-		if (IDX_WIDTH > 11) begin
-			$display("Maximum supported number of cache lines is 2048");
-			$finish;
-		end
-
-
-	localparam integer REQ_DWIDTH = TAG_WIDTH + AGE_WIDTH + 2;
-
-	localparam integer RAM_MODE   = (IDX_WIDTH <= 8) ? 0 : (IDX_WIDTH - 8);
-	localparam integer RAM_DWIDTH = 16 >> RAM_MODE;
-	localparam integer RAM_AWIDTH = 8 + RAM_MODE;
-	localparam integer RAM_COUNT  = (REQ_DWIDTH + RAM_DWIDTH - 1) / RAM_DWIDTH;
-
-	localparam integer MEM_DWIDTH = RAM_COUNT * RAM_DWIDTH;
-	localparam integer FILL = MEM_DWIDTH - REQ_DWIDTH;
-
-	initial
-		$display("Cache tag memory config, %d x %d x %d", RAM_COUNT, 1 << RAM_AWIDTH, RAM_DWIDTH);
-
-
-	// Signals
-	// -------
-
-	wire [RAM_AWIDTH-1:0] w_addr;
-	reg  [RAM_AWIDTH-1:0] w_addr_r;
-	wire [RAM_AWIDTH-1:0] r_addr;
-
-	wire [MEM_DWIDTH-1:0] r_val;
-	wire [MEM_DWIDTH-1:0] w_val;
-	reg  [MEM_DWIDTH-1:0] w_val_r;
-	wire [MEM_DWIDTH-1:0] w_msk;
-	reg  [MEM_DWIDTH-1:0] w_msk_r;
-
-	reg  w_ena_r;
-
-
-	// Mapping
-	// -------
-
-	assign w_addr = { {(RAM_AWIDTH-IDX_WIDTH){1'b0}}, w_idx };
-	assign r_addr = { {(RAM_AWIDTH-IDX_WIDTH){1'b0}}, r_idx };
-
-	assign { r_valid, r_dirty, r_age, r_tag } = r_val[REQ_DWIDTH-1:0];
-	assign w_val = { {FILL{1'b0}},  w_valid,     w_dirty,                w_age,                  w_tag };
-	assign w_msk = { {FILL{1'b1}}, ~w_valid_we, ~w_dirty_we, {AGE_WIDTH{~w_age_we}}, {TAG_WIDTH{~w_tag_we}} };
-
-
-	// Write side reg
-	// --------------
-
-	always @(posedge clk)
-	begin
-		w_addr_r <= w_addr;
-		w_val_r  <= w_val;
-		w_msk_r  <= w_msk;
-		w_ena_r  <= w_ena;
-	end
-
-
-	// Storage elements
-	// ----------------
-
-	genvar i;
-
-	generate
-
-		for (i=0; i<RAM_COUNT; i=i+1)
-			ice40_ebr #(
-				.READ_MODE(RAM_MODE),
-				.WRITE_MODE(RAM_MODE),
-				.MASK_WORKAROUND(1),
-				.NEG_WR_CLK(1)
-			) ram_I (
-				.wr_addr(w_addr_r),
-				.wr_data(w_val_r[i*RAM_DWIDTH+:RAM_DWIDTH]),
-				.wr_mask(w_msk_r[i*RAM_DWIDTH+:RAM_DWIDTH]),
-				.wr_ena(w_ena_r),
-				.wr_clk(clk),
-				.rd_addr(r_addr),
-				.rd_data(r_val[i*RAM_DWIDTH+:RAM_DWIDTH]),
-				.rd_ena(r_ena),
-				.rd_clk(clk)
-			);
-
-	endgenerate
-
-endmodule

+ 0 - 269
cores/mem_cache/sim/mc_core_tb.v

@@ -1,269 +0,0 @@
-/*
- * mc_core_tb.v
- *
- * vim: ts=4 sw=4
- *
- * Copyright (C) 2020  Sylvain Munaut <tnt@246tNt.com>
- * All rights reserved.
- *
- * BSD 3-clause, see LICENSE.bsd
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-`default_nettype none
-`timescale 1ns / 100ps
-
-module mc_core_tb;
-
-	// Signals
-	// -------
-
-	// Cache request/response
-	reg  [19:0] req_addr_pre;
-	reg         req_valid_pre;
-	reg         req_write_pre;
-	reg  [31:0] req_wdata_pre;
-	reg  [ 3:0] req_wmsk_pre;
-
-	reg         req_valid;
-	reg         req_write;
-	reg  [31:0] req_wdata;
-	reg  [ 3:0] req_wmsk;
-
-	wire        resp_ack;
-	wire        resp_nak;
-	wire [31:0] resp_rdata;
-
-	// Memory interface
-	wire [19:0] mi_addr;
-	wire [ 6:0] mi_len;
-	wire        mi_rw;
-	wire        mi_valid;
-	wire        mi_ready;
-
-	wire [31:0] mi_wdata;
-	wire        mi_wack;
-	wire        mi_wlast;
-
-	wire [31:0] mi_rdata;
-	wire        mi_rstb;
-	wire        mi_rlast;
-
-	// Clocks / Sync
-	wire [3:0] clk_read_delay;
-
-	reg  pll_lock = 1'b0;
-	reg  clk = 1'b0;
-	wire rst;
-
-	reg  [3:0] rst_cnt = 4'h8;
-
-
-	// Recording setup
-	// ---------------
-
-	initial begin : dump
-		integer i;
-
-		$dumpfile("mc_core_tb.vcd");
-		$dumpvars(0,mc_core_tb);
-		$dumpvars(0,mc_core_tb);
-
-		for (i=0; i<4; i=i+1) begin
-			$dumpvars(0, mc_core_tb.dut_I.way_valid[i]);
-			$dumpvars(0, mc_core_tb.dut_I.way_dirty[i]);
-			$dumpvars(0, mc_core_tb.dut_I.way_age[i]);
-			$dumpvars(0, mc_core_tb.dut_I.way_tag[i]);
-		end
-	end
-
-
-	// DUT
-	// ---
-
-	mc_core #(
-		.N_WAYS(4),
-		.ADDR_WIDTH(20),
-		.CACHE_LINE(64),
-		.CACHE_SIZE(64)
-	) dut_I (
-		.req_addr_pre(req_addr_pre),
-		.req_valid(req_valid),
-		.req_write(req_write),
-		.req_wdata(req_wdata),
-		.req_wmsk(req_wmsk),
-		.resp_ack(resp_ack),
-		.resp_nak(resp_nak),
-		.resp_rdata(resp_rdata),
-		.mi_addr(mi_addr),
-		.mi_len(mi_len),
-		.mi_rw(mi_rw),
-		.mi_valid(mi_valid),
-		.mi_ready(mi_ready),
-		.mi_wdata(mi_wdata),
-		.mi_wack(mi_wack),
-		.mi_wlast(mi_wlast),
-		.mi_rdata(mi_rdata),
-		.mi_rstb(mi_rstb),
-		.mi_rlast(mi_rlast),
-		.clk(clk),
-		.rst(rst)
-	);
-
-
-
-	// Simulated memory
-	// ----------------
-
-	mem_sim mem_I (
-		.mi_addr(mi_addr),
-		.mi_len(mi_len),
-		.mi_rw(mi_rw),
-		.mi_valid(mi_valid),
-		.mi_ready(mi_ready),
-		.mi_wdata(mi_wdata),
-		.mi_wack(mi_wack),
-		.mi_wlast(mi_wlast),
-		.mi_rdata(mi_rdata),
-		.mi_rstb(mi_rstb),
-		.mi_rlast(mi_rlast),
-		.clk(clk),
-		.rst(rst)
-	);
-
-
-	// Stimulus
-	// --------
-
-	task mc_req_write;
-		input [20:0] addr;
-		input [31:0] data;
-		input [ 3:0] msk;
-		begin
-			req_addr_pre <= addr;
-			req_valid_pre <= 1'b1;
-			req_write_pre <= 1'b1;
-			req_wdata_pre <= data;
-			req_wmsk_pre  <= msk;
-			@(posedge clk);
-
-			req_addr_pre  <= 20'hxxxxx;
-			req_valid_pre <= 1'b0;
-			req_write_pre <= 1'bx;
-			req_wdata_pre <= 32'hxxxxxxxx;
-			req_wmsk_pre  <=  4'hx;
-		end
-	endtask
-
-	task mc_req_read;
-		input [31:0] addr;
-		begin
-			req_addr_pre <= addr;
-			req_valid_pre <= 1'b1;
-			req_write_pre <= 1'b0;
-			@(posedge clk);
-
-			req_addr_pre  <= 20'hxxxxx;
-			req_valid_pre <= 1'b0;
-			req_write_pre <= 1'bx;
-		end
-	endtask
-
-	initial begin
-		// Defaults
-		req_addr_pre  <= 20'hxxxxx;
-		req_valid_pre <= 1'b0;
-		req_write_pre <= 1'bx;
-		req_wdata_pre <= 32'hxxxxxxxx;
-		req_wmsk_pre  <=  4'hx;
-
-		@(negedge rst);
-		@(posedge clk);
-
-		#200 @(posedge clk);
-
-		// Execute 32 byte burst
-		mc_req_read(20'h00010);
-		#200 @(posedge clk);
-		mc_req_read(20'h00010);
-		mc_req_write(20'h0001f, 32'h01234567, 4'h0);
-		mc_req_write(20'h00010, 32'h600dbabe, 4'h0);
-		mc_req_read(20'h0001f);
-
-		mc_req_read(20'h10010);
-		#200 @(posedge clk);
-		mc_req_read(20'h10010);
-		@(posedge clk);
-
-		mc_req_read(20'h20010);
-		#200 @(posedge clk);
-		mc_req_read(20'h20010);
-		@(posedge clk);
-
-		mc_req_read(20'h30010);
-		#200 @(posedge clk);
-		mc_req_read(20'h30010);
-		@(posedge clk);
-
-		mc_req_read(20'h40010);
-		#400 @(posedge clk);
-		mc_req_read(20'h40010);
-		@(posedge clk);
-
-		mc_req_read(20'h20010);
-		@(posedge clk);
-		mc_req_read(20'h20010);
-		@(posedge clk);
-	end
-
-	always @(posedge clk)
-	begin
-		req_valid <= req_valid_pre;
-		req_write <= req_write_pre;
-		req_wdata <= req_wdata_pre;
-		req_wmsk  <= req_wmsk_pre;
-	end
-
-
-	// Clock / Reset
-	// -------------
-
-	// Native clocks
-	initial begin
-		# 200 pll_lock = 1'b1;
-		# 100000 $finish;
-	end
-
-	always #4 clk = ~clk;
-
-	// Reset
-	always @(posedge clk or negedge pll_lock)
-		if (~pll_lock)
-			rst_cnt <= 4'h8;
-		else if (rst_cnt[3])
-			rst_cnt <= rst_cnt + 1;
-
-	assign rst = rst_cnt[3];
-
-endmodule

+ 0 - 264
cores/mem_cache/sim/mc_wb_tb.v

@@ -1,264 +0,0 @@
-/*
- * mc_wb_tb.v
- *
- * vim: ts=4 sw=4
- *
- * Copyright (C) 2020  Sylvain Munaut <tnt@246tNt.com>
- * All rights reserved.
- *
- * BSD 3-clause, see LICENSE.bsd
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-`default_nettype none
-`timescale 1ns / 100ps
-
-module mc_wb_tb;
-
-	// Signals
-	// -------
-
-	// Wishbone bus
-	reg  [19:0] wb_addr;
-	reg  [31:0] wb_wdata;
-	reg  [ 3:0] wb_wmsk;
-	wire [31:0] wb_rdata;
-	reg         wb_cyc;
-	reg         wb_we;
-	wire        wb_ack;
-
-	// Cache request/response
-	wire [19:0] req_addr_pre;
-
-	wire        req_valid;
-	wire        req_write;
-	wire [31:0] req_wdata;
-	wire [ 3:0] req_wmsk;
-
-	wire        resp_ack;
-	wire        resp_nak;
-	wire [31:0] resp_rdata;
-
-	// Memory interface
-	wire [19:0] mi_addr;
-	wire [ 6:0] mi_len;
-	wire        mi_rw;
-	wire        mi_valid;
-	wire        mi_ready;
-
-	wire [31:0] mi_wdata;
-	wire        mi_wack;
-	wire        mi_wlast;
-
-	wire [31:0] mi_rdata;
-	wire        mi_rstb;
-	wire        mi_rlast;
-
-	// Clocks / Sync
-	wire [3:0] clk_read_delay;
-
-	reg  pll_lock = 1'b0;
-	reg  clk = 1'b0;
-	wire rst;
-
-	reg  [3:0] rst_cnt = 4'h8;
-
-
-	// Recording setup
-	// ---------------
-
-	initial begin : dump
-		integer i;
-
-		$dumpfile("mc_wb_tb.vcd");
-		$dumpvars(0,mc_wb_tb);
-		$dumpvars(0,mc_wb_tb);
-
-		for (i=0; i<4; i=i+1) begin
-			$dumpvars(0, mc_wb_tb.dut_I.way_valid[i]);
-			$dumpvars(0, mc_wb_tb.dut_I.way_dirty[i]);
-			$dumpvars(0, mc_wb_tb.dut_I.way_age[i]);
-			$dumpvars(0, mc_wb_tb.dut_I.way_tag[i]);
-		end
-	end
-
-
-	// DUT
-	// ---
-
-	mc_core #(
-		.N_WAYS(4),
-		.ADDR_WIDTH(20),
-		.CACHE_LINE(64),
-		.CACHE_SIZE(64)
-	) dut_I (
-		.req_addr_pre(req_addr_pre),
-		.req_valid(req_valid),
-		.req_write(req_write),
-		.req_wdata(req_wdata),
-		.req_wmsk(req_wmsk),
-		.resp_ack(resp_ack),
-		.resp_nak(resp_nak),
-		.resp_rdata(resp_rdata),
-		.mi_addr(mi_addr),
-		.mi_len(mi_len),
-		.mi_rw(mi_rw),
-		.mi_valid(mi_valid),
-		.mi_ready(mi_ready),
-		.mi_wdata(mi_wdata),
-		.mi_wack(mi_wack),
-		.mi_wlast(mi_wlast),
-		.mi_rdata(mi_rdata),
-		.mi_rstb(mi_rstb),
-		.mi_rlast(mi_rlast),
-		.clk(clk),
-		.rst(rst)
-	);
-
-	mc_bus_wb #(
-		.ADDR_WIDTH(20)
-	) bus_adapt_I (
-		.wb_addr(wb_addr),
-		.wb_wdata(wb_wdata),
-		.wb_wmsk(wb_wmsk),
-		.wb_rdata(wb_rdata),
-		.wb_cyc(wb_cyc),
-		.wb_we(wb_we),
-		.wb_ack(wb_ack),
-		.req_addr_pre(req_addr_pre),
-		.req_valid(req_valid),
-		.req_write(req_write),
-		.req_wdata(req_wdata),
-		.req_wmsk(req_wmsk),
-		.resp_ack(resp_ack),
-		.resp_nak(resp_nak),
-		.resp_rdata(resp_rdata),
-		.clk(clk),
-		.rst(rst)
-	);
-
-
-	// Simulated memory
-	// ----------------
-
-	mem_sim mem_I (
-		.mi_addr(mi_addr),
-		.mi_len(mi_len),
-		.mi_rw(mi_rw),
-		.mi_valid(mi_valid),
-		.mi_ready(mi_ready),
-		.mi_wdata(mi_wdata),
-		.mi_wack(mi_wack),
-		.mi_wlast(mi_wlast),
-		.mi_rdata(mi_rdata),
-		.mi_rstb(mi_rstb),
-		.mi_rlast(mi_rlast),
-		.clk(clk),
-		.rst(rst)
-	);
-
-
-	// Stimulus
-	// --------
-
-	task wb_write;
-		input [19:0] addr;
-		input [31:0] data;
-		begin
-			wb_addr  <= addr;
-			wb_wdata <= data;
-			wb_wmsk  <= 4'h0;
-			wb_we    <= 1'b1;
-			wb_cyc   <= 1'b1;
-
-			@(posedge clk);
-			while (~wb_ack)
-				@(posedge clk);
-
-			wb_addr  <= 4'hx;
-			wb_wdata <= 32'hxxxxxxxx;
-			wb_wmsk  <= 4'hx;
-			wb_we    <= 1'bx;
-			wb_cyc   <= 1'b0;
-		end
-	endtask
-
-	task wb_read;
-		input [19:0] addr;
-		begin
-			wb_addr  <= addr;
-			wb_we    <= 1'b0;
-			wb_cyc   <= 1'b1;
-
-			@(posedge clk);
-			while (~wb_ack)
-				@(posedge clk);
-
-			wb_addr  <= 4'hx;
-			wb_we    <= 1'bx;
-			wb_cyc   <= 1'b0;
-		end
-	endtask
-
-	initial begin
-		// Defaults
-		wb_addr  <= 4'hx;
-		wb_wdata <= 32'hxxxxxxxx;
-		wb_wmsk  <= 4'hx;
-		wb_we    <= 1'bx;
-		wb_cyc   <= 1'b0;
-
-		@(negedge rst);
-		@(posedge clk);
-
-		#200 @(posedge clk);
-
-		wb_write(20'h00010, 32'hcafedead);
-		wb_read (20'h00010);
-		wb_read (20'h00011);
-
-	end
-
-
-	// Clock / Reset
-	// -------------
-
-	// Native clocks
-	initial begin
-		# 200 pll_lock = 1'b1;
-		# 100000 $finish;
-	end
-
-	always #4 clk = ~clk;
-
-	// Reset
-	always @(posedge clk or negedge pll_lock)
-		if (~pll_lock)
-			rst_cnt <= 4'h8;
-		else if (rst_cnt[3])
-			rst_cnt <= rst_cnt + 1;
-
-	assign rst = rst_cnt[3];
-
-endmodule

+ 0 - 190
cores/mem_cache/sim/mem_sim.v

@@ -1,190 +0,0 @@
-/*
- * mem_sim.v
- *
- * vim: ts=4 sw=4
- *
- * Copyright (C) 2020  Sylvain Munaut <tnt@246tNt.com>
- * All rights reserved.
- *
- * BSD 3-clause, see LICENSE.bsd
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-`default_nettype none
-
-module mem_sim #(
-	parameter INIT_FILE = "",
-	parameter integer AW = 20,
-
-	// auto
-	parameter integer AL = AW - 1
-)(
-	// Memory controller interface
-	input  wire [AL:0] mi_addr,
-	input  wire [ 6:0] mi_len,
-	input  wire        mi_rw,
-	input  wire        mi_valid,
-	output wire        mi_ready,
-
-	input  wire [31:0] mi_wdata,
-	output wire        mi_wack,
-	output wire        mi_wlast,
-
-	output wire [31:0] mi_rdata,
-	output wire        mi_rstb,
-	output wire        mi_rlast,
-
-	// Common
-	input  wire clk,
-	input  wire rst
-);
-
-	localparam [1:0]
-		ST_IDLE		= 0,
-		ST_WRITE	= 2,
-		ST_READ		= 3;
-
-
-	// Signals
-	// -------
-
-	// Memory array
-	reg [31:0] mem[0:(1<<AW)-1];
-
-	wire [19:0] mem_addr;
-	wire [31:0] mem_wdata;
-	reg  [31:0] mem_rdata;
-	wire        mem_we;
-
-	// FSM
-	reg  [1:0] state_cur;
-	reg  [1:0] state_nxt;
-
-	// Command counters
-	reg  [19:0] cmd_addr;
-	reg  [ 7:0] cmd_len;
-	wire        cmd_last;
-
-
-	// Memory
-	// ------
-
-	initial
-	begin : mem_init
-		integer a;
-
-		if (INIT_FILE == "") begin
-			for (a=0; a<(1<<20)-1; a=a+1)
-				mem[a] = a;
-		end else begin
-			$readmemh(INIT_FILE, mem);
-		end
-	end
-
-	always @(posedge clk)
-	begin
-		if (mem_we)
-			mem[mem_addr] <= mem_wdata;
-
-		mem_rdata <= mem[mem_addr];
-	end
-
-
-	// Main FSM
-	// --------
-
-	always @(posedge clk)
-		if (rst)
-			state_cur <= ST_IDLE;
-		else
-			state_cur <= state_nxt;
-
-	always @(*)
-	begin
-		// Default is to stay put
-		state_nxt = state_cur;
-
-		// ... or not
-		case (state_cur)
-			ST_IDLE:
-				if (mi_valid)
-					state_nxt = mi_rw ? ST_READ : ST_WRITE;
-
-			ST_READ:
-				if (cmd_last)
-					state_nxt = ST_IDLE;
-
-			ST_WRITE:
-				if (cmd_last)
-					state_nxt = ST_IDLE;
-		endcase
-	end
-
-
-	// Command channel
-	// ---------------
-
-	// Register command
-	always @(posedge clk)
-	begin
-		if (state_cur == ST_IDLE) begin
-			cmd_addr <= mi_addr;
-			cmd_len  <= { 1'b0, mi_len } - 1;
-		end else begin
-			cmd_addr <= cmd_addr + 1;
-			cmd_len  <= cmd_len - 1;
-		end
-	end
-
-	assign cmd_last = cmd_len[7];
-
-	// Ready ?
-	assign mi_ready = (state_cur == ST_IDLE);
-
-	// Mem access
-	assign mem_addr = cmd_addr;
-
-
-	// Write data channel
-	// ------------------
-
-	assign mem_wdata = mi_wdata;
-	delay_bit #(2) dly_we( (state_cur == ST_WRITE), mem_we, clk );
-
-	assign mi_wack  = mem_we;
-	delay_bit #(2) dly_wlast( cmd_last, mi_wlast, clk );
-
-
-	// Read data channel
-	// -----------------
-
-	wire [31:0] mi_rdata_i;
-
-	delay_bus #(5, 32) dly_rdata (mem_rdata, mi_rdata_i, clk);
-	delay_bit #(6)     dly_rstb  ((state_cur == ST_READ), mi_rstb, clk);
-	delay_bit #(6)     dly_rlast ((state_cur == ST_READ) ? cmd_last : 1'bx, mi_rlast, clk);
-
-	assign mi_rdata = mi_rstb ? mi_rdata_i : 32'hxxxxxxxx;
-
-endmodule

+ 0 - 187
cores/mem_cache/sim/mem_sim_tb.v

@@ -1,187 +0,0 @@
-/*
- * mem_sim_tb.v
- *
- * vim: ts=4 sw=4
- *
- * Copyright (C) 2020  Sylvain Munaut <tnt@246tNt.com>
- * All rights reserved.
- *
- * BSD 3-clause, see LICENSE.bsd
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in the
- *       documentation and/or other materials provided with the distribution.
- *     * Neither the name of the <organization> nor the
- *       names of its contributors may be used to endorse or promote products
- *       derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-`default_nettype none
-`timescale 1ns / 100ps
-
-module mem_sim_tb;
-
-	// Signals
-	// -------
-
-	// Memory interface
-	reg  [19:0] mi_addr;
-	reg  [ 6:0] mi_len;
-	reg         mi_rw;
-	reg         mi_valid;
-	wire        mi_ready;
-
-	reg  [31:0] mi_wdata;
-	wire        mi_wack;
-	wire        mi_wlast;
-
-	wire [31:0] mi_rdata;
-	wire        mi_rstb;
-	wire        mi_rlast;
-
-	// Clocks / Sync
-	wire [3:0] clk_read_delay;
-
-	reg  pll_lock = 1'b0;
-	reg  clk = 1'b0;
-	wire rst;
-
-	reg  [3:0] rst_cnt = 4'h8;
-
-
-	// Recording setup
-	// ---------------
-
-	initial begin
-		$dumpfile("mem_sim_tb.vcd");
-		$dumpvars(0,mem_sim_tb);
-	end
-
-
-	// DUT
-	// ---
-
-	mem_sim dut_I (
-		.mi_addr(mi_addr),
-		.mi_len(mi_len),
-		.mi_rw(mi_rw),
-		.mi_valid(mi_valid),
-		.mi_ready(mi_ready),
-		.mi_wdata(mi_wdata),
-		.mi_wack(mi_wack),
-		.mi_wlast(mi_wlast),
-		.mi_rdata(mi_rdata),
-		.mi_rstb(mi_rstb),
-		.mi_rlast(mi_rlast),
-		.clk(clk),
-		.rst(rst)
-	);
-
-
-	// Mem interface
-	// -------------
-
-	always @(posedge clk)
-		if (rst)
-			mi_wdata <= 32'h00010203;
-		else if (mi_wack)
-			mi_wdata <= mi_wdata + 32'h04040404;
-
-
-	// Stimulus
-	// --------
-
-	task mi_burst_write;
-		input [31:0] addr;
-		input [ 6:0] len;
-		begin
-			mi_addr  <= addr;
-			mi_len   <= len;
-			mi_rw    <= 1'b0;
-			mi_valid <= 1'b1;
-
-			@(posedge clk);
-			while (~mi_ready)
-				@(posedge clk);
-
-			mi_valid <= 1'b0;
-
-			@(posedge clk);
-		end
-	endtask
-
-	task mi_burst_read;
-		input [31:0] addr;
-		input [ 6:0] len;
-		begin
-			mi_addr  <= addr;
-			mi_len   <= len;
-			mi_rw    <= 1'b1;
-			mi_valid <= 1'b1;
-
-			@(posedge clk);
-			while (~mi_ready)
-				@(posedge clk);
-
-			mi_valid <= 1'b0;
-
-			@(posedge clk);
-		end
-	endtask
-
-	initial begin
-		// Defaults
-		mi_addr  <= 32'hxxxxxxxx;
-		mi_len   <= 7'hx;
-		mi_rw    <= 1'bx;
-		mi_valid <= 1'b0;
-
-		@(negedge rst);
-		@(posedge clk);
-
-		#200 @(posedge clk);
-
-		// Execute 32 byte burst
-		mi_burst_read (32'h00002000, 7'd15);
-		mi_burst_write(32'h00002000, 7'd31);
-		mi_burst_read (32'h00002000, 7'd15);
-		mi_burst_write(32'h00003000, 7'd31);
-	end
-
-
-	// Clock / Reset
-	// -------------
-
-	// Native clocks
-	initial begin
-		# 200 pll_lock = 1'b1;
-		# 100000 $finish;
-	end
-
-	always #4 clk = ~clk;
-
-	// Reset
-	always @(posedge clk or negedge pll_lock)
-		if (~pll_lock)
-			rst_cnt <= 4'h8;
-		else if (rst_cnt[3])
-			rst_cnt <= rst_cnt + 1;
-
-	assign rst = rst_cnt[3];
-
-endmodule

+ 1 - 0
cores/no2memcache

@@ -0,0 +1 @@
+Subproject commit abf7e4a9b6e444e30d08f20efe9cc6b8eaddeab4

+ 1 - 1
projects/riscv_doom/Makefile

@@ -1,7 +1,7 @@
 # Project config
 PROJ = riscv_doom
 
-PROJ_DEPS := no2usb no2misc no2ice40 no2qpimem mem_cache video
+PROJ_DEPS := no2usb no2misc no2ice40 no2qpimem no2memcache video
 PROJ_RTL_SRCS := $(addprefix rtl/, \
 	vid_top.v \
 	vid_palette.v \