OpenCores
URL https://opencores.org/ocsvn/mpmc8/mpmc8/trunk

Subversion Repositories mpmc8

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /mpmc8/trunk
    from Rev 4 to Rev 5
    Reverse comparison

Rev 4 → Rev 5

/rtl/mpmc10/README.md
0,0 → 1,42
# MPMC10 - Multiport Memory Controller
## Overview
The multi-port memory controller provides eight access ports with either small streaming read caches or a 64kB shared read cache to the ddr3 ram. The multi-port memory controller interfaces between the SoC and a MIG controller.
Ports may be customized with parameter settings. Port #5 is setup to handle sprites and is read-only.
## New Features
* Version 10 of the controller supports a larger system cache and the cache now supports write operations.
* The controller now has an input fifo to queue requests to improve performance.
* All ports are now 128-bit.
* Ports are serviced in a round-robin fashion.
# Cache / Streaming Cache
The cache is a 64kB 4-way associative cache which may be shared between ports. The cache line size is 16 bytes. The cache allows ports to read in parallel but only supports a single write port.
The streaming caches are much smaller read caches. They are useful when the data is generally read and used only once, as for a frame buffer for instance. The streaming caches are an alternative to making the read cache multi-way associative, and effectively add ways to the cache reads.
Streaming caches are typically loaded using large data bursts. They are setup for 64 beat bursts which load 1kB of data. Given the large burst size and small cache size there are only a handful of cache tags required which helps to reduce the footprint.
 
## Suggested Port Usage
 
|Port|Use |Port Bits|Common Cache|Stream Buffer|
|----|--------------------------------|---------|-------------|-------------|
| 0 |Frame Buffer / Bitmap Controller| 128 | | * |
| 1 |CPU #1 | 128 | * | |
| 2 |Ethernet Controller | 128 | * | |
| 3 |Audio Controller | 128 | | * |
| 4 |Graphics Accelerator | 128 | * | |
| 5 |Sprite Controller | 128 | | * |
| 6 |SD (disk) Controller | 128 | * | |
| 7 |CPU #2 | 128 | * | |
 
## Port Priorities
Ports are serviced in a round robin fashion.
 
## Clocks
Each port may have it own clock. Clock domain crossing logic is present for incoming and outgoing signals. The controller's clock typically runs at 1/4 the PHY clock or 100MHz. The port clocks may be a different frequency.
 
## Memory Access
Memory is accessed in strips of 16 bytes which is the size that MIG interface uses. Specifying multiple strips for reading will use a burst of strips which is a much faster way to access memory.
 
## Address Reservations
The controller supports address reservations on memory for imnplementation of semaphores. The CPU must output address reservation set and clear signals to support this.
 
## Parameters
STREAMn - cause port number 'n' to use a streaming cache instead of the main cache
NAR - sets the number of outstanding address reservation that are present, this should be a small number (eg. 2)
/rtl/mpmc10/mpcm10_cache.sv
0,0 → 1,412
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import faxi_pkg::*;
import mpmc10_pkg::*;
 
module mpmc10_cache(input rst, wclk, inv,
input faxi_write_request256_t wchi,
output faxi_write_response_t wcho,
input faxi_write_request256_t ld,
input ch0clk,
input ch1clk,
input ch2clk,
input ch3clk,
input ch4clk,
input ch5clk,
input ch6clk,
input ch7clk,
input faxi_read_request_t ch0i,
input faxi_read_request_t ch1i,
input faxi_read_request_t ch2i,
input faxi_read_request_t ch3i,
input faxi_read_request_t ch4i,
input faxi_read_request_t ch5i,
input faxi_read_request_t ch6i,
input faxi_read_request_t ch7i,
output faxi_read_response256_t ch0o,
output faxi_read_response256_t ch1o,
output faxi_read_response256_t ch2o,
output faxi_read_response256_t ch3o,
output faxi_read_response256_t ch4o,
output faxi_read_response256_t ch5o,
output faxi_read_response256_t ch6o,
output faxi_read_response256_t ch7o
);
 
integer n,n2,n3;
 
(* ram_style="distributed" *)
reg [127:0] vbit [0:CACHE_ASSOC-1];
 
reg [31:0] radrr0;
reg [31:0] radrr1;
reg [31:0] radrr2;
reg [31:0] radrr3;
reg [31:0] radrr4;
reg [31:0] radrr5;
reg [31:0] radrr6;
reg [31:0] radrr7;
reg [31:0] radrr8;
 
mpmc10_cache_line_t doutb [0:8][0:3];
mpmc10_cache_line_t wrdata, wdata;
reg [31:0] wadr;
reg [35:0] wstrb;
reg [1:0] wway;
reg wvalid;
 
reg [CACHE_ASSOC-1:0] vbito0a;
reg [CACHE_ASSOC-1:0] vbito1a;
reg [CACHE_ASSOC-1:0] vbito2a;
reg [CACHE_ASSOC-1:0] vbito3a;
reg [CACHE_ASSOC-1:0] vbito4a;
reg [CACHE_ASSOC-1:0] vbito5a;
reg [CACHE_ASSOC-1:0] vbito6a;
reg [CACHE_ASSOC-1:0] vbito7a;
reg [CACHE_ASSOC-1:0] vbito8a;
 
reg [CACHE_ASSOC-1:0] hit0a;
reg [CACHE_ASSOC-1:0] hit1a;
reg [CACHE_ASSOC-1:0] hit2a;
reg [CACHE_ASSOC-1:0] hit3a;
reg [CACHE_ASSOC-1:0] hit4a;
reg [CACHE_ASSOC-1:0] hit5a;
reg [CACHE_ASSOC-1:0] hit6a;
reg [CACHE_ASSOC-1:0] hit7a;
reg [CACHE_ASSOC-1:0] hit8a;
 
// Always ready to accept a read request.
assign ch0o.ARREADY = 1'b1;
assign ch1o.ARREADY = 1'b1;
assign ch2o.ARREADY = 1'b1;
assign ch3o.ARREADY = 1'b1;
assign ch4o.ARREADY = 1'b1;
assign ch5o.ARREADY = 1'b1;
assign ch6o.ARREADY = 1'b1;
assign ch7o.ARREADY = 1'b1;
 
always_ff @(posedge ch0clk) radrr0 <= ch0i.ad.AADDR;
always_ff @(posedge ch1clk) radrr1 <= ch1i.ad.AADDR;
always_ff @(posedge ch2clk) radrr2 <= ch2i.ad.AADDR;
always_ff @(posedge ch3clk) radrr3 <= ch3i.ad.AADDR;
always_ff @(posedge ch4clk) radrr4 <= ch4i.ad.AADDR;
always_ff @(posedge ch5clk) radrr5 <= ch5i.ad.AADDR;
always_ff @(posedge ch6clk) radrr6 <= ch6i.ad.AADDR;
always_ff @(posedge ch7clk) radrr7 <= ch7i.ad.AADDR;
 
always_ff @(posedge ch0clk) ch0o.RID <= ch0i.ad.AID;
always_ff @(posedge ch1clk) ch1o.RID <= ch1i.ad.AID;
always_ff @(posedge ch2clk) ch2o.RID <= ch2i.ad.AID;
always_ff @(posedge ch3clk) ch3o.RID <= ch3i.ad.AID;
always_ff @(posedge ch4clk) ch4o.RID <= ch4i.ad.AID;
always_ff @(posedge ch5clk) ch5o.RID <= ch5i.ad.AID;
always_ff @(posedge ch6clk) ch6o.RID <= ch6i.ad.AID;
always_ff @(posedge ch7clk) ch7o.RID <= ch7i.ad.AID;
 
reg [8:0] rclkp;
always_comb
begin
rclkp[0] = ch0clk;
rclkp[1] = ch1clk;
rclkp[2] = ch2clk;
rclkp[3] = ch3clk;
rclkp[4] = ch4clk;
rclkp[5] = ch5clk;
rclkp[6] = ch6clk;
rclkp[7] = ch7clk;
rclkp[8] = wclk;
end
 
reg [6:0] radr [0:8];
always_comb
begin
radr[0] = ch0i.ad.AADDR[11:5];
radr[1] = ch1i.ad.AADDR[11:5];
radr[2] = ch2i.ad.AADDR[11:5];
radr[3] = ch3i.ad.AADDR[11:5];
radr[4] = ch4i.ad.AADDR[11:5];
radr[5] = ch5i.ad.AADDR[11:5];
radr[6] = ch6i.ad.AADDR[11:5];
radr[7] = ch7i.ad.AADDR[11:5];
radr[8] = wchi.ad.AADDR[11:5];
end
 
// xpm_memory_sdpram: Simple Dual Port RAM
// Xilinx Parameterized Macro, version 2020.2
 
genvar gway,gport;
 
generate begin : gCacheRAM
for (gport = 0; gport < 9; gport = gport + 1)
for (gway = 0; gway < CACHE_ASSOC; gway = gway + 1)
xpm_memory_sdpram #(
.ADDR_WIDTH_A(7), // DECIMAL
.ADDR_WIDTH_B(7), // DECIMAL
.AUTO_SLEEP_TIME(0), // DECIMAL
.BYTE_WRITE_WIDTH_A(8), // DECIMAL
.CASCADE_HEIGHT(0), // DECIMAL
.CLOCKING_MODE("independent_clock"), // String
.ECC_MODE("no_ecc"), // String
.MEMORY_INIT_FILE("none"), // String
.MEMORY_INIT_PARAM("0"), // String
.MEMORY_OPTIMIZATION("true"), // String
.MEMORY_PRIMITIVE("block"), // String
.MEMORY_SIZE($bits(mpmc10_cache_line_t)*128), // DECIMAL
.MESSAGE_CONTROL(0), // DECIMAL
.READ_DATA_WIDTH_B($bits(mpmc10_cache_line_t)), // DECIMAL
.READ_LATENCY_B(1), // DECIMAL
.READ_RESET_VALUE_B("0"), // String
.RST_MODE_A("SYNC"), // String
.RST_MODE_B("SYNC"), // String
.SIM_ASSERT_CHK(0), // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
.USE_EMBEDDED_CONSTRAINT(0), // DECIMAL
.USE_MEM_INIT(1), // DECIMAL
.WAKEUP_TIME("disable_sleep"), // String
.WRITE_DATA_WIDTH_A($bits(mpmc10_cache_line_t)), // DECIMAL
.WRITE_MODE_B("no_change") // String
)
xpm_memory_sdpram_inst (
.dbiterrb(), // 1-bit output: Status signal to indicate double bit error occurrence
// on the data output of port B.
 
.doutb(doutb[gport][gway]), // READ_DATA_WIDTH_B-bit output: Data output for port B read operations.
.sbiterrb(), // 1-bit output: Status signal to indicate single bit error occurrence
// on the data output of port B.
 
.addra(wadr[11:5]), // ADDR_WIDTH_A-bit input: Address for port A write operations.
.addrb(radr[gport]), // ADDR_WIDTH_B-bit input: Address for port B read operations.
.clka(wclk), // 1-bit input: Clock signal for port A. Also clocks port B when
// parameter CLOCKING_MODE is "common_clock".
 
.clkb(rclkp[gport]), // 1-bit input: Clock signal for port B when parameter CLOCKING_MODE is
// "independent_clock". Unused when parameter CLOCKING_MODE is
// "common_clock".
 
.dina(wdata), // WRITE_DATA_WIDTH_A-bit input: Data input for port A write operations.
.ena(wvalid & |wstrb & wway==gway), // 1-bit input: Memory enable signal for port A. Must be high on clock
// cycles when write operations are initiated. Pipelined internally.
 
.enb(1'b1), // 1-bit input: Memory enable signal for port B. Must be high on clock
// cycles when read operations are initiated. Pipelined internally.
 
.injectdbiterra(1'b0), // 1-bit input: Controls double bit error injection on input data when
// ECC enabled (Error injection capability is not available in
// "decode_only" mode).
 
.injectsbiterra(1'b0), // 1-bit input: Controls single bit error injection on input data when
// ECC enabled (Error injection capability is not available in
// "decode_only" mode).
 
.regceb(1'b1), // 1-bit input: Clock Enable for the last register stage on the output
// data path.
 
.rstb(rst), // 1-bit input: Reset signal for the final port B output register stage.
// Synchronously resets output port doutb to the value specified by
// parameter READ_RESET_VALUE_B.
 
.sleep(1'b0), // 1-bit input: sleep signal to enable the dynamic power saving feature.
.wea(wstrb) // WRITE_DATA_WIDTH_A/BYTE_WRITE_WIDTH_A-bit input: Write enable vector
// for port A input data port dina. 1 bit wide when word-wide writes are
// used. In byte-wide write configurations, each bit controls the
// writing one byte of dina to address addra. For example, to
// synchronously write only bits [15-8] of dina when WRITE_DATA_WIDTH_A
// is 32, wea would be 4'b0010.
 
);
end
endgenerate
genvar g;
generate begin : gReaddat
for (g = 0; g < CACHE_ASSOC; g = g + 1) begin
always_ff @(posedge ch0clk) vbito0a[g] <= vbit[g][radrr0[11:5]];
always_ff @(posedge ch1clk) vbito1a[g] <= vbit[g][radrr1[11:5]];
always_ff @(posedge ch2clk) vbito2a[g] <= vbit[g][radrr2[11:5]];
always_ff @(posedge ch3clk) vbito3a[g] <= vbit[g][radrr3[11:5]];
always_ff @(posedge ch4clk) vbito4a[g] <= vbit[g][radrr4[11:5]];
always_ff @(posedge ch5clk) vbito5a[g] <= vbit[g][radrr5[11:5]];
always_ff @(posedge ch6clk) vbito6a[g] <= vbit[g][radrr6[11:5]];
always_ff @(posedge ch7clk) vbito7a[g] <= vbit[g][radrr7[11:5]];
always_ff @(posedge wclk) vbito8a[g] <= vbit[g][radrr8[11:5]];
always_comb hit0a[g] = (doutb[0][g].tag==radrr0[31:13]) && (vbito0a[g]==1'b1);
always_comb hit1a[g] = (doutb[1][g].tag==radrr1[31:13]) && (vbito1a[g]==1'b1);
always_comb hit2a[g] = (doutb[2][g].tag==radrr2[31:13]) && (vbito2a[g]==1'b1);
always_comb hit3a[g] = (doutb[3][g].tag==radrr3[31:13]) && (vbito3a[g]==1'b1);
always_comb hit4a[g] = (doutb[4][g].tag==radrr4[31:13]) && (vbito4a[g]==1'b1);
always_comb hit5a[g] = (doutb[5][g].tag==radrr5[31:13]) && (vbito5a[g]==1'b1);
always_comb hit6a[g] = (doutb[6][g].tag==radrr6[31:13]) && (vbito6a[g]==1'b1);
always_comb hit7a[g] = (doutb[7][g].tag==radrr7[31:13]) && (vbito7a[g]==1'b1);
always_comb hit8a[g] = (doutb[8][g].tag==radrr8[31:13]) && (vbito8a[g]==1'b1);
always_ff @(posedge ch0clk) ch0o.RLAST <= ch0i.ad.ACOUNT==ch0i.ad.ALEN;
always_ff @(posedge ch1clk) ch1o.RLAST <= ch1i.ad.ACOUNT==ch1i.ad.ALEN;
always_ff @(posedge ch2clk) ch2o.RLAST <= ch2i.ad.ACOUNT==ch2i.ad.ALEN;
always_ff @(posedge ch3clk) ch3o.RLAST <= ch3i.ad.ACOUNT==ch3i.ad.ALEN;
always_ff @(posedge ch4clk) ch4o.RLAST <= ch4i.ad.ACOUNT==ch4i.ad.ALEN;
always_ff @(posedge ch5clk) ch5o.RLAST <= ch5i.ad.ACOUNT==ch5i.ad.ALEN;
always_ff @(posedge ch6clk) ch6o.RLAST <= ch6i.ad.ACOUNT==ch6i.ad.ALEN;
always_ff @(posedge ch7clk) ch7o.RLAST <= ch7i.ad.ACOUNT==ch7i.ad.ALEN;
always_comb ch0o.RVALID = |hit0a;
always_comb ch1o.RVALID = |hit1a;
always_comb ch2o.RVALID = |hit2a;
always_comb ch3o.RVALID = |hit3a;
always_comb ch4o.RVALID = |hit4a;
always_comb ch5o.RVALID = |hit5a;
always_comb ch6o.RVALID = |hit6a;
always_comb ch7o.RVALID = |hit7a;
end
end
endgenerate
 
always_comb
begin
ch0o.RDATA <= 'd0;
ch1o.RDATA <= 'd0;
ch2o.RDATA <= 'd0;
ch3o.RDATA <= 'd0;
ch4o.RDATA <= 'd0;
ch5o.RDATA <= 'd0;
ch6o.RDATA <= 'd0;
ch7o.RDATA <= 'd0;
wrdata <= 'd0;
for (n2 = 0; n2 < CACHE_ASSOC; n2 = n2 + 1) begin
if (hit0a[n2]) ch0o.RDATA <= doutb[0][n2];
if (hit1a[n2]) ch1o.RDATA <= doutb[1][n2];
if (hit2a[n2]) ch2o.RDATA <= doutb[2][n2];
if (hit3a[n2]) ch3o.RDATA <= doutb[3][n2];
if (hit4a[n2]) ch4o.RDATA <= doutb[4][n2];
if (hit5a[n2]) ch5o.RDATA <= doutb[5][n2];
if (hit6a[n2]) ch6o.RDATA <= doutb[6][n2];
if (hit7a[n2]) ch7o.RDATA <= doutb[7][n2];
if (hit8a[n2]) wrdata <= doutb[8][n2];
end
end
 
always_comb
begin
ch0o.ARWAY <= 2'd0;
ch1o.ARWAY <= 2'd0;
ch2o.ARWAY <= 2'd0;
ch3o.ARWAY <= 2'd0;
ch4o.ARWAY <= 2'd0;
ch5o.ARWAY <= 2'd0;
ch6o.ARWAY <= 2'd0;
ch7o.ARWAY <= 2'd0;
wway <= 2'd0;
for (n3 = 0; n3 < CACHE_ASSOC; n3 = n3 + 1) begin
if (hit0a[n3]) ch0o.ARWAY <= n3;
if (hit1a[n3]) ch1o.ARWAY <= n3;
if (hit2a[n3]) ch2o.ARWAY <= n3;
if (hit3a[n3]) ch3o.ARWAY <= n3;
if (hit4a[n3]) ch4o.ARWAY <= n3;
if (hit5a[n3]) ch5o.ARWAY <= n3;
if (hit6a[n3]) ch6o.ARWAY <= n3;
if (hit7a[n3]) ch7o.ARWAY <= n3;
if (hit8a[n3]) wway <= n3;
end
end
 
always_ff @(posedge wclk)
if (rst) begin
for (n = 0; n < 4; n = n + 1)
vbit[n] <= 'b0;
end
else begin
if (|wchi.WSTRB)
vbit[wchi.ad.AWAY][wchi.ad.AADDR[11:5]] <= 1'b1;
else if (inv)
vbit[wchi.ad.AWAY][wchi.ad.AADDR[11:5]] <= 1'b0;
end
 
// Pass back decode error to indicate a miss.
always_comb ch0o.RRESP = |hit0a ? FAXI_OKAY : FAXI_DECERR;
always_comb ch1o.RRESP = |hit1a ? FAXI_OKAY : FAXI_DECERR;
always_comb ch2o.RRESP = |hit2a ? FAXI_OKAY : FAXI_DECERR;
always_comb ch3o.RRESP = |hit3a ? FAXI_OKAY : FAXI_DECERR;
always_comb ch4o.RRESP = |hit4a ? FAXI_OKAY : FAXI_DECERR;
always_comb ch5o.RRESP = |hit5a ? FAXI_OKAY : FAXI_DECERR;
always_comb ch6o.RRESP = |hit6a ? FAXI_OKAY : FAXI_DECERR;
always_comb ch7o.RRESP = |hit7a ? FAXI_OKAY : FAXI_DECERR;
 
// Update the cache only if there was a write hit or if loading the cache line
// due to a read miss. For a read miss the entire line is updated, otherwise
// just the part of the line relevant to the write is updated.
always_ff @(posedge wclk)
begin
wadr <= ld.ad.AWVALID ? ld.ad.AWADDR : wchi.ad.AWADDR;
wstrb <= ld.WVALID ? ld.WSTRB : wchi.WSTRB & {36{|hit8a}};
wvalid <= ld.WVALID ? 1'b1 : wchi.WVALID & |hit8a;
end
 
// Merge write data into cache line.
generate begin : gWrData
for (g = 0; g < 32; g = g + 1)
always_comb
if (ld.WVALID)
wdata[g*8+7:g*8] <= ld.WDATA[g*8+7:g*8];
else
wdata[g*8+7:g*8] <= wstrb[g] ? wchi.WDATA[g*8+7:g*8] : wrdata[g*8+7:g*8];
always_comb
wdata[263:256] <= wstrb[32] ? (ld.WVALID ? {ld.WTAG,ld.WMOD} : {wchi.WTAG,wchi.WMOD}) : wrdata[263:256];
always_comb
wdata[287:264] <= wstrb[33] ? (ld.WVALID ? {ld.WTAG,ld.WMOD} : {wchi.WTAG,wchi.WMOD}) : wrdata[287:264];
end
endgenerate
 
// Writes take two clock cycles, 1 to read the RAM and find out if it is a
// write hit and a second clock to write the data.
reg awready;
always_ff @(posedge wclk)
if (rst)
awready <= 1'b1;
else begin
awready <= 1'b1;
wcho.BRESP <= FAXI_SLVERR;
wcho.BVALID <= 1'b0;
if (wchi.AWVALID)
awready <= 1'b0;
if (wchi.AWVALID & ~ld.AWVALID) begin
wcho.BRESP <= FAXI_OKAY;
wcho.BID <= wchi.AWID;
wcho.BVALID <= 1'b1;
end
end
always_comb wcho.AWREADY = awready;
 
endmodule
/rtl/mpmc10/mpcm10_cache_wb.sv
0,0 → 1,515
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import const_pkg::*;
import wishbone_pkg::*;
import mpmc10_pkg::*;
 
module mpmc10_cache_wb (input rst, wclk, inv,
input wb_write_request128_t wchi,
output wb_write_response_t wcho,
input wb_write_request128_t ld,
input ch0clk,
input ch1clk,
input ch2clk,
input ch3clk,
input ch4clk,
input ch5clk,
input ch6clk,
input ch7clk,
input wb_write_request128_t ch0i,
input wb_write_request128_t ch1i,
input wb_write_request128_t ch2i,
input wb_write_request128_t ch3i,
input wb_write_request128_t ch4i,
input wb_write_request128_t ch5i,
input wb_write_request128_t ch6i,
input wb_write_request128_t ch7i,
input ch0wack,
input ch1wack,
input ch2wack,
input ch3wack,
input ch4wack,
input ch5wack,
input ch6wack,
input ch7wack,
output wb_read_response128_t ch0o,
output wb_read_response128_t ch1o,
output wb_read_response128_t ch2o,
output wb_read_response128_t ch3o,
output wb_read_response128_t ch4o,
output wb_read_response128_t ch5o,
output wb_read_response128_t ch6o,
output wb_read_response128_t ch7o
);
parameter DEP=1024;
parameter LOBIT=4;
parameter HIBIT=13;
 
integer n,n2,n3,n4,n5;
 
(* ram_style="distributed" *)
reg [1023:0] vbit [0:CACHE_ASSOC-1];
initial begin
for (n5 = 0; n5 < CACHE_ASSOC; n5 = n5 + 1)
vbit[n5] <= 'd0;
end
 
reg [31:0] radrr [0:8];
reg wchi_stb, wchi_stb_r;
reg [15:0] wchi_sel, wchi_sel_r;
reg [31:0] wchi_adr;
reg [127:0] wchi_dat;
 
mpmc10_quad_cache_line_t doutb [0:8];
mpmc10_quad_cache_line_t wrdata, wdata;
 
reg [31:0] wadr;
reg wstrb;
reg [$clog2(CACHE_ASSOC)-1:0] wway;
 
reg [CACHE_ASSOC-1:0] vbito0a;
reg [CACHE_ASSOC-1:0] vbito1a;
reg [CACHE_ASSOC-1:0] vbito2a;
reg [CACHE_ASSOC-1:0] vbito3a;
reg [CACHE_ASSOC-1:0] vbito4a;
reg [CACHE_ASSOC-1:0] vbito5a;
reg [CACHE_ASSOC-1:0] vbito6a;
reg [CACHE_ASSOC-1:0] vbito7a;
reg [CACHE_ASSOC-1:0] vbito8a;
 
reg [CACHE_ASSOC-1:0] hit0a;
reg [CACHE_ASSOC-1:0] hit1a;
reg [CACHE_ASSOC-1:0] hit2a;
reg [CACHE_ASSOC-1:0] hit3a;
reg [CACHE_ASSOC-1:0] hit4a;
reg [CACHE_ASSOC-1:0] hit5a;
reg [CACHE_ASSOC-1:0] hit6a;
reg [CACHE_ASSOC-1:0] hit7a;
reg [CACHE_ASSOC-1:0] hit8a;
 
reg stb0;
reg stb1;
reg stb2;
reg stb3;
reg stb4;
reg stb5;
reg stb6;
reg stb7;
reg [8:0] rstb;
 
always_ff @(posedge ch0clk) radrr[0] <= ch0i.adr;
always_ff @(posedge ch1clk) radrr[1] <= ch1i.adr;
always_ff @(posedge ch2clk) radrr[2] <= ch2i.adr;
always_ff @(posedge ch3clk) radrr[3] <= ch3i.adr;
always_ff @(posedge ch4clk) radrr[4] <= ch4i.adr;
always_ff @(posedge ch5clk) radrr[5] <= ch5i.adr;
always_ff @(posedge ch6clk) radrr[6] <= ch6i.adr;
always_ff @(posedge ch7clk) radrr[7] <= ch7i.adr;
always_ff @(posedge wclk) radrr[8] <= ld.cyc ? ld.adr : wchi.adr;
always_ff @(posedge wclk) wchi_adr <= radrr[8];
 
always_ff @(posedge ch0clk) stb0 <= ch0i.stb;
always_ff @(posedge ch1clk) stb1 <= ch1i.stb;
always_ff @(posedge ch2clk) stb2 <= ch2i.stb;
always_ff @(posedge ch3clk) stb3 <= ch3i.stb;
always_ff @(posedge ch4clk) stb4 <= ch4i.stb;
always_ff @(posedge ch5clk) stb5 <= ch5i.stb;
always_ff @(posedge ch6clk) stb6 <= ch6i.stb;
always_ff @(posedge ch7clk) stb7 <= ch7i.stb;
 
always_comb rstb[0] <= ch0i.stb & ~ch0i.we;
always_comb rstb[1] <= ch1i.stb & ~ch1i.we;
always_comb rstb[2] <= ch2i.stb & ~ch2i.we;
always_comb rstb[3] <= ch3i.stb & ~ch3i.we;
always_comb rstb[4] <= ch4i.stb & ~ch4i.we;
always_comb rstb[5] <= ch5i.stb & ~ch5i.we;
always_comb rstb[6] <= ch6i.stb & ~ch6i.we;
always_comb rstb[7] <= ch7i.stb & ~ch7i.we;
always_comb rstb[8] <= ld.stb | wchi.stb;
 
always_ff @(posedge wclk) wchi_stb_r <= wchi.stb;
always_ff @(posedge wclk) wchi_stb <= wchi_stb_r;
always_ff @(posedge wclk) wchi_sel_r <= wchi.sel;
always_ff @(posedge wclk) wchi_sel <= wchi_sel_r;
always_ff @(posedge wclk) wchi_dat <= wchi.dat;
 
reg [8:0] rclkp;
always_comb
begin
rclkp[0] = ch0clk;
rclkp[1] = ch1clk;
rclkp[2] = ch2clk;
rclkp[3] = ch3clk;
rclkp[4] = ch4clk;
rclkp[5] = ch5clk;
rclkp[6] = ch6clk;
rclkp[7] = ch7clk;
rclkp[8] = wclk;
end
 
reg [HIBIT-LOBIT:0] radr [0:8];
always_comb
begin
radr[0] = ch0i.adr[HIBIT:LOBIT];
radr[1] = ch1i.adr[HIBIT:LOBIT];
radr[2] = ch2i.adr[HIBIT:LOBIT];
radr[3] = ch3i.adr[HIBIT:LOBIT];
radr[4] = ch4i.adr[HIBIT:LOBIT];
radr[5] = ch5i.adr[HIBIT:LOBIT];
radr[6] = ch6i.adr[HIBIT:LOBIT];
radr[7] = ch7i.adr[HIBIT:LOBIT];
radr[8] = ld.cyc ? ld.adr[HIBIT:LOBIT] : wchi.adr[HIBIT:LOBIT];
end
 
// xpm_memory_sdpram: Simple Dual Port RAM
// Xilinx Parameterized Macro, version 2020.2
 
genvar gway,gport;
 
generate begin : gCacheRAM
for (gport = 0; gport < 9; gport = gport + 1) begin
xpm_memory_sdpram #(
.ADDR_WIDTH_A($clog2(DEP)),
.ADDR_WIDTH_B($clog2(DEP)),
.AUTO_SLEEP_TIME(0),
.BYTE_WRITE_WIDTH_A($bits(mpmc10_quad_cache_line_t)),
.CASCADE_HEIGHT(0),
.CLOCKING_MODE("independent_clock"), // String
.ECC_MODE("no_ecc"), // String
.MEMORY_INIT_FILE("none"), // String
.MEMORY_INIT_PARAM("0"), // String
.MEMORY_OPTIMIZATION("true"), // String
.MEMORY_PRIMITIVE("block"), // String
.MEMORY_SIZE($bits(mpmc10_quad_cache_line_t)*DEP), // DECIMAL
.MESSAGE_CONTROL(0), // DECIMAL
.READ_DATA_WIDTH_B($bits(mpmc10_quad_cache_line_t)), // DECIMAL
.READ_LATENCY_B(1),
.READ_RESET_VALUE_B("0"), // String
.RST_MODE_A("SYNC"), // String
.RST_MODE_B("SYNC"), // String
.SIM_ASSERT_CHK(0), // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
.USE_EMBEDDED_CONSTRAINT(0),
.USE_MEM_INIT(1),
.WAKEUP_TIME("disable_sleep"), // String
.WRITE_DATA_WIDTH_A($bits(mpmc10_quad_cache_line_t)), // DECIMAL
.WRITE_MODE_B("no_change") // String
)
xpm_memory_sdpram_inst1 (
.dbiterrb(), // 1-bit output: Status signal to indicate double bit error occurrence
// on the data output of port B.
 
.doutb(doutb[gport]), // READ_DATA_WIDTH_B-bit output: Data output for port B read operations.
.sbiterrb(), // 1-bit output: Status signal to indicate single bit error occurrence
// on the data output of port B.
 
.addra(wadr2[HIBIT:LOBIT]), // ADDR_WIDTH_A-bit input: Address for port A write operations.
.addrb(radr[gport]), // ADDR_WIDTH_B-bit input: Address for port B read operations.
.clka(wclk), // 1-bit input: Clock signal for port A. Also clocks port B when
// parameter CLOCKING_MODE is "common_clock".
 
.clkb(rclkp[gport]), // 1-bit input: Clock signal for port B when parameter CLOCKING_MODE is
// "independent_clock". Unused when parameter CLOCKING_MODE is
// "common_clock".
 
.dina(wdata), // WRITE_DATA_WIDTH_A-bit input: Data input for port A write operations.
.ena(wstrb), // 1-bit input: Memory enable signal for port A. Must be high on clock
// cycles when write operations are initiated. Pipelined internally.
 
.enb(rstb[gport]), // 1-bit input: Memory enable signal for port B. Must be high on clock
// cycles when read operations are initiated. Pipelined internally.
 
.injectdbiterra(1'b0), // 1-bit input: Controls double bit error injection on input data when
// ECC enabled (Error injection capability is not available in
// "decode_only" mode).
 
.injectsbiterra(1'b0), // 1-bit input: Controls single bit error injection on input data when
// ECC enabled (Error injection capability is not available in
// "decode_only" mode).
 
.regceb(1'b1), // 1-bit input: Clock Enable for the last register stage on the output
// data path.
 
.rstb(rst), // 1-bit input: Reset signal for the final port B output register stage.
// Synchronously resets output port doutb to the value specified by
// parameter READ_RESET_VALUE_B.
 
.sleep(1'b0), // 1-bit input: sleep signal to enable the dynamic power saving feature.
.wea(wstrb) // WRITE_DATA_WIDTH_A/BYTE_WRITE_WIDTH_A-bit input: Write enable vector
// for port A input data port dina. 1 bit wide when word-wide writes are
// used. In byte-wide write configurations, each bit controls the
// writing one byte of dina to address addra. For example, to
// synchronously write only bits [15-8] of dina when WRITE_DATA_WIDTH_A
// is 32, wea would be 4'b0010.
 
);
end
end
endgenerate
genvar g;
generate begin : gReaddat
for (g = 0; g < CACHE_ASSOC; g = g + 1) begin
always_comb vbito0a[g] <= vbit[g][radrr[0][HIBIT:LOBIT]];
always_comb vbito1a[g] <= vbit[g][radrr[1][HIBIT:LOBIT]];
always_comb vbito2a[g] <= vbit[g][radrr[2][HIBIT:LOBIT]];
always_comb vbito3a[g] <= vbit[g][radrr[3][HIBIT:LOBIT]];
always_comb vbito4a[g] <= vbit[g][radrr[4][HIBIT:LOBIT]];
always_comb vbito5a[g] <= vbit[g][radrr[5][HIBIT:LOBIT]];
always_comb vbito6a[g] <= vbit[g][radrr[6][HIBIT:LOBIT]];
always_comb vbito7a[g] <= vbit[g][radrr[7][HIBIT:LOBIT]];
always_comb vbito8a[g] <= vbit[g][radrr[8][HIBIT:LOBIT]];
always_ff @(posedge ch0clk) hit0a[g] = (doutb[0].lines[g].tag==radrr[0][31:HIBIT+1]) && (vbito0a[g]==1'b1);
always_ff @(posedge ch1clk) hit1a[g] = (doutb[1].lines[g].tag==radrr[1][31:HIBIT+1]) && (vbito1a[g]==1'b1);
always_ff @(posedge ch2clk) hit2a[g] = (doutb[2].lines[g].tag==radrr[2][31:HIBIT+1]) && (vbito2a[g]==1'b1);
always_ff @(posedge ch3clk) hit3a[g] = (doutb[3].lines[g].tag==radrr[3][31:HIBIT+1]) && (vbito3a[g]==1'b1);
always_ff @(posedge ch4clk) hit4a[g] = (doutb[4].lines[g].tag==radrr[4][31:HIBIT+1]) && (vbito4a[g]==1'b1);
always_ff @(posedge ch5clk) hit5a[g] = (doutb[5].lines[g].tag==radrr[5][31:HIBIT+1]) && (vbito5a[g]==1'b1);
always_ff @(posedge ch6clk) hit6a[g] = (doutb[6].lines[g].tag==radrr[6][31:HIBIT+1]) && (vbito6a[g]==1'b1);
always_ff @(posedge ch7clk) hit7a[g] = (doutb[7].lines[g].tag==radrr[7][31:HIBIT+1]) && (vbito7a[g]==1'b1);
always_ff @(posedge wclk) hit8a[g] = (doutb[8].lines[g].tag==radrr[8][31:HIBIT+1]) && (vbito8a[g]==1'b1);
end
always_comb ch0o.ack = (|hit0a & stb0) | (ch0wack & stb0);
always_comb ch1o.ack = (|hit1a & stb1) | (ch1wack & stb1);
always_comb ch2o.ack = (|hit2a & stb2) | (ch2wack & stb2);
always_comb ch3o.ack = (|hit3a & stb3) | (ch3wack & stb3);
always_comb ch4o.ack = (|hit4a & stb4) | (ch4wack & stb4);
always_comb ch5o.ack = (|hit5a & stb5) | (ch5wack & stb5);
always_comb ch6o.ack = (|hit6a & stb6) | (ch6wack & stb6);
always_comb ch7o.ack = (|hit7a & stb7) | (ch7wack & stb7);
always_comb ch0o.err = 1'b0;
always_comb ch1o.err = 1'b0;
always_comb ch2o.err = 1'b0;
always_comb ch3o.err = 1'b0;
always_comb ch4o.err = 1'b0;
always_comb ch5o.err = 1'b0;
always_comb ch6o.err = 1'b0;
always_comb ch7o.err = 1'b0;
always_comb ch0o.rty = 1'b0;
always_comb ch1o.rty = 1'b0;
always_comb ch2o.rty = 1'b0;
always_comb ch3o.rty = 1'b0;
always_comb ch4o.rty = 1'b0;
always_comb ch5o.rty = 1'b0;
always_comb ch6o.rty = 1'b0;
always_comb ch7o.rty = 1'b0;
always_comb ch0o.cid = ch0i.cid;
always_comb ch1o.cid = ch1i.cid;
always_comb ch2o.cid = ch2i.cid;
always_comb ch3o.cid = ch3i.cid;
always_comb ch4o.cid = ch4i.cid;
always_comb ch5o.cid = ch5i.cid;
always_comb ch6o.cid = ch6i.cid;
always_comb ch7o.cid = ch7i.cid;
end
endgenerate
 
always_comb wway = hit8a[0] ? 2'd0 : hit8a[1] ? 2'd1 : hit8a[2] ? 2'd2 : hit8a[3] ? 2'd3 : 2'd0;
 
always_comb
begin
ch0o.dat <= 'd0;
ch1o.dat <= 'd0;
ch2o.dat <= 'd0;
ch3o.dat <= 'd0;
ch4o.dat <= 'd0;
ch5o.dat <= 'd0;
ch6o.dat <= 'd0;
ch7o.dat <= 'd0;
wrdata <= 'd0;
for (n2 = 0; n2 < CACHE_ASSOC; n2 = n2 + 1) begin
if (hit0a[n2]) ch0o.dat <= doutb[0].lines[n2];
if (hit1a[n2]) ch1o.dat <= doutb[1].lines[n2];
if (hit2a[n2]) ch2o.dat <= doutb[2].lines[n2];
if (hit3a[n2]) ch3o.dat <= doutb[3].lines[n2];
if (hit4a[n2]) ch4o.dat <= doutb[4].lines[n2];
if (hit5a[n2]) ch5o.dat <= doutb[5].lines[n2];
if (hit6a[n2]) ch6o.dat <= doutb[6].lines[n2];
if (hit7a[n2]) ch7o.dat <= doutb[7].lines[n2];
end
// if (|hit8a)
wrdata <= doutb[8];
end
 
reg b0,b1,b2;
reg ldcycd1,ldcycd2;
always_ff @(posedge wclk)
ldcycd1 <= ld.cyc;
always_ff @(posedge wclk)
ldcycd2 <= ldcycd1;
always_ff @(posedge wclk)
if (rst) begin
for (n = 0; n < 4; n = n + 1)
vbit[n] <= 'b0;
end
else begin
if (ldcycd2) begin
vbit[0][wadr2[HIBIT:LOBIT]] <= 1'b1;
vbit[1][wadr2[HIBIT:LOBIT]] <= b0;
vbit[2][wadr2[HIBIT:LOBIT]] <= b1;
vbit[3][wadr2[HIBIT:LOBIT]] <= b2;
end
if (ldcycd1) begin
b0 <= vbit[0][wadr[HIBIT:LOBIT]];
b1 <= vbit[1][wadr[HIBIT:LOBIT]];
b2 <= vbit[2][wadr[HIBIT:LOBIT]];
end
if (|wchi_sel & wchi_stb & ~(ld.cyc|ldcycd1|ldcycd2))
vbit[wway][wadr[HIBIT:LOBIT]] <= 1'b1;
else if (inv)
vbit[wway][wadr[HIBIT:LOBIT]] <= 1'b0;
end
 
// Update the cache only if there was a write hit or if loading the cache line
// due to a read miss. For a read miss the entire line is updated, otherwise
// just the part of the line relevant to the write is updated.
always_ff @(posedge wclk)
begin
if (ld.cyc)
wadr <= ld.adr;
else if (wchi_stb)
wadr <= wchi_adr;
wstrb <= ldcycd2 | (wchi_stb & |hit8a);
end
reg [127:0] lddat1, lddat2;
reg [31:0] wadr2;
always_ff @(posedge wclk)
wadr2 <= wadr;
always_ff @(posedge wclk)
lddat1 <= ld.dat;
always_ff @(posedge wclk)
lddat2 <= lddat1;
// Merge write data into cache line.
// For a load due to a read miss the entire line is updated.
// For a write hit, just the portion of the line corresponding to the hit is
// updated.
reg [18:0] t0,t1,t2;
reg m0,m1,m2;
generate begin : gWrData
// LRU update
always_ff @(posedge wclk)
begin
if (ldcycd2) begin
wdata.lines[0].tag <= {5'd0,wadr2[31:HIBIT+1]}; // set tag
wdata.lines[1].tag <= t0;
wdata.lines[2].tag <= t1;
wdata.lines[3].tag <= t2;
wdata.lines[0].modified <= 1'b0; // clear modified flags
wdata.lines[1].modified <= m0;
wdata.lines[2].modified <= m1;
wdata.lines[3].modified <= m2;
end
if (ldcycd1) begin
t0 <= wrdata.lines[0].tag;
t1 <= wrdata.lines[1].tag;
t2 <= wrdata.lines[2].tag;
m0 <= wrdata.lines[0].modified;
m1 <= wrdata.lines[1].modified;
m2 <= wrdata.lines[2].modified;
end
if (!(ld.cyc|ldcycd1|ldcycd2)) begin
if (wchi_stb & hit8a[0])
wdata.lines[0].modified <= 1'b1;
else
wdata.lines[0].modified <= wrdata.lines[0].modified;
if (wchi_stb & hit8a[1])
wdata.lines[1].modified <= 1'b1;
else
wdata.lines[1].modified <= wrdata.lines[0].modified;
if (wchi_stb & hit8a[2])
wdata.lines[2].modified <= 1'b1;
else
wdata.lines[2].modified <= wrdata.lines[0].modified;
if (wchi_stb & hit8a[3])
wdata.lines[3].modified <= 1'b1;
else
wdata.lines[3].modified <= wrdata.lines[0].modified;
// Tag stays the same, it was hit
wdata.lines[0].tag <= wrdata.lines[0].tag;
wdata.lines[1].tag <= wrdata.lines[1].tag;
wdata.lines[2].tag <= wrdata.lines[2].tag;
wdata.lines[3].tag <= wrdata.lines[3].tag;
end
end
for (g = 0; g < 16; g = g + 1)
always_ff @(posedge wclk)
begin
if (ldcycd2) begin
// wdata <= wrdata << $bits(mpmc10_cache_line_t);
wdata.lines[0].data[g*8+7:g*8] <= lddat2[g*8+7:g*8]; // set data
wdata.lines[1].data[g*8+7:g*8] <= wrdata.lines[0].data[g*8+7:g*8];
wdata.lines[2].data[g*8+7:g*8] <= wrdata.lines[1].data[g*8+7:g*8];
wdata.lines[3].data[g*8+7:g*8] <= wrdata.lines[2].data[g*8+7:g*8];
end
if (!(ld.cyc|ldcycd1|ldcycd2)) begin
if (wchi_stb & hit8a[0])
wdata.lines[0].data[g*8+7:g*8] <= wchi_sel[g] ? wchi_dat[g*8+7:g*8] : wrdata.lines[0].data[g*8+7:g*8];
else
wdata.lines[0].data[g*8+7:g*8] <= wrdata.lines[0].data[g*8+7:g*8];
if (wchi_stb & hit8a[1])
wdata.lines[1].data[g*8+7:g*8] <= wchi_sel[g] ? wchi_dat[g*8+7:g*8] : wrdata.lines[1].data[g*8+7:g*8];
else
wdata.lines[1].data[g*8+7:g*8] <= wrdata.lines[0].data[g*8+7:g*8];
if (wchi_stb & hit8a[2])
wdata.lines[2].data[g*8+7:g*8] <= wchi_sel[g] ? wchi_dat[g*8+7:g*8] : wrdata.lines[2].data[g*8+7:g*8];
else
wdata.lines[2].data[g*8+7:g*8] <= wrdata.lines[0].data[g*8+7:g*8];
if (wchi_stb & hit8a[3])
wdata.lines[3].data[g*8+7:g*8] <= wchi_sel[g] ? wchi_dat[g*8+7:g*8] : wrdata.lines[3].data[g*8+7:g*8];
else
wdata.lines[3].data[g*8+7:g*8] <= wrdata.lines[0].data[g*8+7:g*8];
end
end
end
endgenerate
 
// Writes take two clock cycles, 1 to read the RAM and find out if it is a
// write hit and a second clock to write the data. The write cycle may be
// delayed by a cycle due to a load.
reg wack;
always_ff @(posedge wclk)
if (rst)
wack <= 1'b0;
else begin
wack <= 1'b0;
if (wchi.stb & ~ld.stb)
wack <= 1'b1;
end
assign wcho.ack = wack & wchi.stb;
 
endmodule
/rtl/mpmc10/mpcm10_strm_read_cache.sv
0,0 → 1,158
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import mpmc10_pkg::*;
 
module mpmc10_strm_read_cache(rst, wclk, wr, wadr, wdat, inv,
rclk, rd, radr, rdat, hit
);
input rst;
input wclk;
input wr;
input [31:0] wadr;
input [127:0] wdat;
input inv;
input rclk;
input rd;
input [31:0] radr;
output [127:0] rdat;
output reg hit;
 
(* ram_style="distributed" *)
reg [18:0] tags [0:7];
(* ram_style="distributed" *)
reg [7:0] vbit;
reg [31:0] radrr;
reg [18:0] tago;
reg vbito;
 
xpm_memory_sdpram #(
.ADDR_WIDTH_A(9), // DECIMAL
.ADDR_WIDTH_B(9), // DECIMAL
.AUTO_SLEEP_TIME(0), // DECIMAL
.BYTE_WRITE_WIDTH_A(128), // DECIMAL
.CASCADE_HEIGHT(0), // DECIMAL
.CLOCKING_MODE("independent_clock"), // String
.ECC_MODE("no_ecc"), // String
.MEMORY_INIT_FILE("none"), // String
.MEMORY_INIT_PARAM("0"), // String
.MEMORY_OPTIMIZATION("true"), // String
.MEMORY_PRIMITIVE("block"), // String
.MEMORY_SIZE(512*128), // DECIMAL
.MESSAGE_CONTROL(0), // DECIMAL
.READ_DATA_WIDTH_B(128), // DECIMAL
.READ_LATENCY_B(1), // DECIMAL
.READ_RESET_VALUE_B("0"), // String
.RST_MODE_A("SYNC"), // String
.RST_MODE_B("SYNC"), // String
.SIM_ASSERT_CHK(0), // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
.USE_EMBEDDED_CONSTRAINT(0), // DECIMAL
.USE_MEM_INIT(1), // DECIMAL
.WAKEUP_TIME("disable_sleep"), // String
.WRITE_DATA_WIDTH_A(128), // DECIMAL
.WRITE_MODE_B("no_change") // String
)
xpm_memory_sdpram_inst (
.dbiterrb(), // 1-bit output: Status signal to indicate double bit error occurrence
// on the data output of port B.
 
.doutb(rdat), // READ_DATA_WIDTH_B-bit output: Data output for port B read operations.
.sbiterrb(), // 1-bit output: Status signal to indicate single bit error occurrence
// on the data output of port B.
 
.addra(wadr[12:4]), // ADDR_WIDTH_A-bit input: Address for port A write operations.
.addrb(radr[12:4]), // ADDR_WIDTH_B-bit input: Address for port B read operations.
.clka(wclk), // 1-bit input: Clock signal for port A. Also clocks port B when
// parameter CLOCKING_MODE is "common_clock".
 
.clkb(rclk), // 1-bit input: Clock signal for port B when parameter CLOCKING_MODE is
// "independent_clock". Unused when parameter CLOCKING_MODE is
// "common_clock".
 
.dina(wdat), // WRITE_DATA_WIDTH_A-bit input: Data input for port A write operations.
.ena(wr), // 1-bit input: Memory enable signal for port A. Must be high on clock
// cycles when write operations are initiated. Pipelined internally.
 
.enb(rd), // 1-bit input: Memory enable signal for port B. Must be high on clock
// cycles when read operations are initiated. Pipelined internally.
 
.injectdbiterra(1'b0), // 1-bit input: Controls double bit error injection on input data when
// ECC enabled (Error injection capability is not available in
// "decode_only" mode).
 
.injectsbiterra(1'b0), // 1-bit input: Controls single bit error injection on input data when
// ECC enabled (Error injection capability is not available in
// "decode_only" mode).
 
.regceb(1'b1), // 1-bit input: Clock Enable for the last register stage on the output
// data path.
 
.rstb(rst), // 1-bit input: Reset signal for the final port B output register stage.
// Synchronously resets output port doutb to the value specified by
// parameter READ_RESET_VALUE_B.
 
.sleep(1'b0), // 1-bit input: sleep signal to enable the dynamic power saving feature.
.wea(wr) // WRITE_DATA_WIDTH_A/BYTE_WRITE_WIDTH_A-bit input: Write enable vector
// for port A input data port dina. 1 bit wide when word-wide writes are
// used. In byte-wide write configurations, each bit controls the
// writing one byte of dina to address addra. For example, to
// synchronously write only bits [15-8] of dina when WRITE_DATA_WIDTH_A
// is 32, wea would be 4'b0010.
 
);
 
always_ff @(posedge rclk)
radrr <= radr;
always_ff @(posedge wclk)
if (wr && wadr[9:4]==6'h3F)
tags[wadr[12:10]] <= wadr[31:13];
always_comb
tago <= tags[radrr[12:10]];
always_comb // @(posedge rclk)
vbito <= vbit[radrr[12:10]];
always_ff @(posedge wclk)
if (rst)
vbit <= 'b0;
else begin
if (wr && wadr[9:4]==6'h3F)
vbit[wadr[12:10]] <= 1'b1;
else if (inv)
vbit[wadr[12:10]] <= 1'b0;
end
always_comb
hit = (tago==radrr[31:13]) && (vbito==1'b1);
 
endmodule
/rtl/mpmc10/mpmc10_addr_gen.sv
0,0 → 1,62
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import mpmc10_pkg::*;
 
module mpmc10_addr_gen(rst, clk, state, rdy, num_strips, strip_cnt, addr_base, addr);
input rst;
input clk;
input [3:0] state;
input rdy;
input [5:0] num_strips;
input [5:0] strip_cnt;
input [31:0] addr_base;
output reg [31:0] addr;
 
always_ff @(posedge clk)
if (rst)
addr <= 32'h1FFFFFFF;
else begin
if (state==mpmc10_pkg::PRESET2)
addr <= addr_base;
else if (state==mpmc10_pkg::READ_DATA1 && rdy && strip_cnt != num_strips)
addr[31:4] <= addr[31:4] + 2'd1;
// Increment the address if we had to start a new burst.
// else if (state==WRITE_DATA3 && req_strip_cnt!=num_strips)
// app_addr <= app_addr + {req_strip_cnt,4'h0}; // works for only 1 missed burst
end
 
endmodule
/rtl/mpmc10/mpmc10_addr_resv_man.sv
0,0 → 1,189
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import mpmc10_pkg::*;
 
module mpmc10_addr_resv_man(rst, clk, state,
adr0, adr1, adr2, adr3, adr4, adr5, adr6, adr7,
sr0, sr1, sr2, sr3, sr4, sr5, sr6, sr7,
wch, we, wadr, cr, ch1_taghit,
resv_ch, resv_adr, rack);
parameter NAR = 2;
input rst;
input clk;
input [3:0] state;
input [31:0] adr0;
input [31:0] adr1;
input [31:0] adr2;
input [31:0] adr3;
input [31:0] adr4;
input [31:0] adr5;
input [31:0] adr6;
input [31:0] adr7;
input sr0;
input sr1;
input sr2;
input sr3;
input sr4;
input sr5;
input sr6;
input sr7;
input [3:0] wch;
input cr;
input we;
input [31:0] wadr;
input ch1_taghit;
output reg [3:0] resv_ch [0:NAR-1];
output reg [31:0] resv_adr [0:NAR-1];
output reg [7:0] rack; // reservation acknowledged
 
reg [19:0] resv_to_cnt;
wire [2:0] enc;
wire [7:0] srr = {sr7,sr6,sr5,sr4,sr3,sr2,sr1,sr0};
wire [31:0] adr [0:7];
 
assign adr[0] = adr0;
assign adr[1] = adr1;
assign adr[2] = adr2;
assign adr[3] = adr3;
assign adr[4] = adr4;
assign adr[5] = adr5;
assign adr[6] = adr6;
assign adr[7] = adr7;
 
roundRobin urr1
(
.rst(rst),
.clk(clk),
.ce(1'b1),
.req(srr),
.lock(8'h00),
.sel(),
.sel_enc(enc)
);
 
// For address reservation below
reg [7:0] match;
always @(posedge clk)
if (rst)
match <= 8'h00;
else begin
if (match >= NAR)
match <= 8'h00;
else
match <= match + 8'd1;
end
 
always_comb
rack = ~srr | srr[enc];
// Managing address reservations
integer n7;
always_ff @(posedge clk)
if (rst) begin
resv_to_cnt <= 20'd0;
for (n7 = 0; n7 < NAR; n7 = n7 + 1)
resv_ch[n7] <= 4'hF;
end
else begin
resv_to_cnt <= resv_to_cnt + 20'd1;
 
for (n7 = 0; n7 < 8; n7 = n7 + 1)
if (enc==n7 && |srr)
reserve_adr({1'b0,n7[2:0]},adr[n7]);
 
if (state==mpmc10_pkg::IDLE) begin
if (we) begin
if (cr) begin
for (n7 = 0; n7 < NAR; n7 = n7 + 1)
if ((resv_ch[n7]==wch) && (resv_adr[n7][31:4]==wadr[31:4]))
resv_ch[n7] <= 4'hF;
end
end
end
end
 
integer empty_resv;
function resv_held;
input [3:0] ch;
input [31:0] adr;
integer n8;
begin
resv_held = mpmc10_pkg::FALSE;
for (n8 = 0; n8 < NAR; n8 = n8 + 1)
if (resv_ch[n8]==ch && resv_adr[n8][31:5]==adr[31:5])
resv_held = mpmc10_pkg::TRUE;
end
endfunction
 
// Find an empty reservation bucket
integer n9;
always_comb
begin
empty_resv <= -1;
for (n9 = 0; n9 < NAR; n9 = n9 + 1)
if (resv_ch[n9]==4'hF)
empty_resv <= n9;
end
 
// Two reservation buckets are allowed for. There are two (or more) CPU's in the
// system and as long as they are not trying to control the same resource (the
// same semaphore) then they should be able to set a reservation. Ideally there
// could be more reservation buckets available, but it starts to be a lot of
// hardware.
task reserve_adr;
input [3:0] ch;
input [31:0] adr;
begin
// Ignore an attempt to reserve an address that's already reserved. The LWAR
// instruction is usually called in a loop and we don't want it to use up
// all address reservations.
if (!resv_held(ch,adr)) begin
if (empty_resv >= 0) begin
resv_ch[empty_resv] <= ch;
resv_adr[empty_resv] <= adr;
end
// Here there were no free reservation buckets, so toss one of the
// old reservations out.
else begin
resv_ch[match] <= ch;
resv_adr[match] <= adr;
end
end
end
endtask
 
endmodule
/rtl/mpmc10/mpmc10_app_cmd_gen.sv
0,0 → 1,57
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import mpmc10_pkg::*;
 
module mpmc10_app_cmd_gen(clk, state, cmd);
input clk;
input [3:0] state;
output reg [2:0] cmd;
 
// Strangely, for the DDR3 the default is to have a write command value,
// overridden when a read is needed. The command is processed by the
// WRITE_DATAx states.
// Transition CMD only when EN is low.
 
always_ff @(posedge clk)
begin
if (state==IDLE)
cmd <= CMD_WRITE;
else if (state==READ_DATA0)
cmd <= CMD_READ;
end
 
endmodule
/rtl/mpmc10/mpmc10_app_en_gen.sv
0,0 → 1,62
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import mpmc10_pkg::*;
 
module mpmc10_app_en_gen(clk, state, rdy, strip_cnt, num_strips, en);
input clk;
input [3:0] state;
input rdy;
input [5:0] strip_cnt;
input [5:0] num_strips;
output reg en;
 
// app_en latches the command and address when app_rdy is active. If app_rdy
// is not true, the command must be retried.
always_ff @(posedge clk)
begin
en <= mpmc10_pkg::FALSE;
if (state==mpmc10_pkg::WRITE_DATA1)
en <= mpmc10_pkg::TRUE;
else if (state==mpmc10_pkg::WRITE_DATA2 && !rdy)
en <= mpmc10_pkg::TRUE;
else if (state==mpmc10_pkg::READ_DATA0)
en <= mpmc10_pkg::TRUE;
else if (state==mpmc10_pkg::READ_DATA1 && !(rdy && strip_cnt==num_strips))
en <= mpmc10_pkg::TRUE;
end
 
endmodule
/rtl/mpmc10/mpmc10_app_wdf_end_gen.sv
0,0 → 1,56
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import mpmc10_pkg::*;
 
module mpmc10_app_wdf_end_gen(clk, state, rdy, strip_cnt, num_strips, wend);
input clk;
input [3:0] state;
input rdy;
input [5:0] strip_cnt;
input [5:0] num_strips;
output reg wend;
 
// app_wdf_wren is used to strobe data into the data fifo when app_wdf_rdy is
// true.
always_ff @(posedge clk)
begin
wend <= mpmc10_pkg::FALSE;
if (state==mpmc10_pkg::WRITE_DATA0 && rdy)
wend <= strip_cnt==num_strips;
end
 
endmodule
/rtl/mpmc10/mpmc10_app_wdf_wren_gen.sv
0,0 → 1,54
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import mpmc10_pkg::*;
 
module mpmc10_app_wdf_wren_gen(clk, state, rdy, wren);
input clk;
input [3:0] state;
input rdy;
output reg wren;
 
// app_wdf_wren is used to strobe data into the data fifo when app_wdf_rdy is
// true.
always_ff @(posedge clk)
begin
wren <= mpmc10_pkg::FALSE;
if (state==mpmc10_pkg::WRITE_DATA0 && rdy)
wren <= mpmc10_pkg::TRUE;
end
 
endmodule
/rtl/mpmc10/mpmc10_cache_test.sv
0,0 → 1,172
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import const_pkg::*;
import wishbone_pkg::*;
import mpmc10_pkg::*;
 
module mpmc10_cache_test();
 
reg rst;
reg clk;
reg wclk;
reg ch6clk;
typedef enum logic [5:0] {
ST1 = 6'd1,
ST2,ST3,ST4,ST5
} state_t;
state_t state;
 
initial begin
clk = 1'b0;
wclk = 1'b0;
ch6clk = 1'b0;
rst = 1'b0;
#5 rst = 1'b1;
#305 rst = 1'b0;
end
 
always #5 clk = ~clk;
always #5 wclk = ~wclk;
always #12 ch6clk = ~ch6clk;
 
reg [7:0] count, count2;
wb_write_request128_t ld, ch6i;
wb_read_response128_t ch6o;
 
mpmc10_cache_wb ucache1
(
.rst(rst),
.wclk(wclk),
.inv(1'b0),
.wchi('d0),
.wcho(),
.ld(ld),
.ch0i('d0),
.ch1i('d0),
.ch2i('d0),
.ch3i('d0),
.ch4i('d0),
.ch5i('d0),
.ch6i(ch6i),
.ch7i('d0),
.ch0clk(1'b0),
.ch1clk(1'b0),
.ch2clk(1'b0),
.ch3clk(1'b0),
.ch4clk(1'b0),
.ch5clk(1'b0),
.ch6clk(ch6clk),
.ch7clk(1'b0),
.ch0wack(),
.ch1wack(),
.ch2wack(),
.ch3wack(),
.ch4wack(),
.ch5wack(),
.ch6wack(1'b0),
.ch7wack(),
.ch0o(),
.ch1o(),
.ch2o(),
.ch3o(),
.ch4o(),
.ch5o(),
.ch6o(ch6o),
.ch7o()
);
 
always @(posedge ch6clk)
if (rst)
state <= ST1;
else begin
case(state)
ST1: state <= ST2;
ST2: state <= ST3;
ST3: state <= ST4;
ST4:
if (ch6o.ack)
state <= ST5;
ST5: state <= ST1;
default: state <= ST1;
endcase
end
 
always @(posedge wclk)
if (rst) begin
ld <= 'd0;
count <= 'd0;
end
else begin
case(state)
ST1,ST2,ST3,ST4:
begin
ld.cyc <= 1'b1;
ld.stb <= 1'b1;
ld.we <= 1'b0;
ld.adr <= 32'h300000 + {count,4'h0};
ld.dat <= {8{16'h7C00}};
ld.sel <= -1;
count <= count + 2'd1;
end
endcase
end
 
 
always @(posedge ch6clk)
if (rst) begin
ch6i <= 'd0;
count2 <= 'd0;
end
else
case(state)
ST3:
begin
ch6i.cyc <= 1'b1;
ch6i.stb <= 1'b1;
ch6i.we <= 1'b0;
ch6i.sel <= -1;
ch6i.adr <= 32'h300000 + {count2,4'h0};
end
ST4:
if (ch6o.ack) begin
ch6i.cyc <= 1'b0;
ch6i.stb <= 1'b0;
count2 <= count2 + 2'd1;
end
endcase
 
endmodule
/rtl/mpmc10/mpmc10_chcnt.sv
0,0 → 1,61
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
module mpmc10_chcnt(rst, clk, hit, cnt);
parameter BITS=7;
input rst;
input clk;
input hit;
output reg [BITS-1:0] cnt;
 
reg hit1;
 
always_ff @(posedge clk)
if (rst) begin
cnt <= {1'b1,{BITS-1{1'b0}}};
hit1 <= 1'b0;
end
else begin
hit1 <= hit;
if (hit)
cnt <= {1'b1,{BITS-1{1'b0}}};
else if (hit1 & ~hit) // neg. edge on hit
cnt <= 'd0;
else if (!cnt[BITS-1])
cnt <= cnt + 2'd1;
end
 
endmodule
/rtl/mpmc10/mpmc10_data_select.sv
0,0 → 1,52
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import mpmc10_pkg::*;
 
module mpmc10_data_select(clk, state, dati, dato);
parameter WID=256;
input clk;
input [3:0] state;
input [WID-1:0] dati;
output reg [WID-1:0] dato;
 
// Setting the write data
always_ff @(posedge clk)
if (state==mpmc10_pkg::IDLE) begin
dato <= dati;
end
 
endmodule
/rtl/mpmc10/mpmc10_fifo.sv
0,0 → 1,164
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import mpmc10_pkg::*;
 
module mpmc10_fifo(rst, clk, rd_fifo, wr_fifo, req_fifoi, req_fifoo, v,
full, empty, almost_full, rd_rst_busy, wr_rst_busy, cnt);
input rst;
input clk;
input rd_fifo;
input wr_fifo;
input wb_write_request128_t req_fifoi;
output wb_write_request128_t req_fifoo;
output v;
output full;
output empty;
output almost_full;
output rd_rst_busy;
output wr_rst_busy;
output [4:0] cnt;
 
xpm_fifo_sync #(
.DOUT_RESET_VALUE("0"), // String
.ECC_MODE("no_ecc"), // String
.FIFO_MEMORY_TYPE("distributed"), // String
.FIFO_READ_LATENCY(1), // DECIMAL
.FIFO_WRITE_DEPTH(32), // DECIMAL
.FULL_RESET_VALUE(0), // DECIMAL
.PROG_EMPTY_THRESH(3), // DECIMAL
.PROG_FULL_THRESH(27), // DECIMAL
.RD_DATA_COUNT_WIDTH(5), // DECIMAL
.READ_DATA_WIDTH($bits(wb_write_request128_t)), // DECIMAL
.READ_MODE("std"), // String
.SIM_ASSERT_CHK(0), // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
.USE_ADV_FEATURES("070F"), // String
.WAKEUP_TIME(0), // DECIMAL
.WRITE_DATA_WIDTH($bits(wb_write_request128_t)), // DECIMAL
.WR_DATA_COUNT_WIDTH(5) // DECIMAL
)
xpm_fifo_sync_inst (
.almost_empty(), // 1-bit output: Almost Empty : When asserted, this signal indicates that
// only one more read can be performed before the FIFO goes to empty.
 
.almost_full(almost_full), // 1-bit output: Almost Full: When asserted, this signal indicates that
// only one more write can be performed before the FIFO is full.
 
.data_valid(v), // 1-bit output: Read Data Valid: When asserted, this signal indicates
// that valid data is available on the output bus (dout).
 
.dbiterr(), // 1-bit output: Double Bit Error: Indicates that the ECC decoder detected
// a double-bit error and data in the FIFO core is corrupted.
 
.dout(req_fifoo), // READ_DATA_WIDTH-bit output: Read Data: The output data bus is driven
// when reading the FIFO.
 
.empty(empty), // 1-bit output: Empty Flag: When asserted, this signal indicates that the
// FIFO is empty. Read requests are ignored when the FIFO is empty,
// initiating a read while empty is not destructive to the FIFO.
 
.full(full), // 1-bit output: Full Flag: When asserted, this signal indicates that the
// FIFO is full. Write requests are ignored when the FIFO is full,
// initiating a write when the FIFO is full is not destructive to the
// contents of the FIFO.
 
.overflow(), // 1-bit output: Overflow: This signal indicates that a write request
// (wren) during the prior clock cycle was rejected, because the FIFO is
// full. Overflowing the FIFO is not destructive to the contents of the
// FIFO.
 
.prog_empty(), // 1-bit output: Programmable Empty: This signal is asserted when the
// number of words in the FIFO is less than or equal to the programmable
// empty threshold value. It is de-asserted when the number of words in
// the FIFO exceeds the programmable empty threshold value.
 
.prog_full(), // 1-bit output: Programmable Full: This signal is asserted when the
// number of words in the FIFO is greater than or equal to the
// programmable full threshold value. It is de-asserted when the number of
// words in the FIFO is less than the programmable full threshold value.
 
.rd_data_count(), // RD_DATA_COUNT_WIDTH-bit output: Read Data Count: This bus indicates the
// number of words read from the FIFO.
 
.rd_rst_busy(rd_rst_busy), // 1-bit output: Read Reset Busy: Active-High indicator that the FIFO read
// domain is currently in a reset state.
 
.sbiterr(), // 1-bit output: Single Bit Error: Indicates that the ECC decoder detected
// and fixed a single-bit error.
 
.underflow(), // 1-bit output: Underflow: Indicates that the read request (rd_en) during
// the previous clock cycle was rejected because the FIFO is empty. Under
// flowing the FIFO is not destructive to the FIFO.
 
.wr_ack(), // 1-bit output: Write Acknowledge: This signal indicates that a write
// request (wr_en) during the prior clock cycle is succeeded.
 
.wr_data_count(cnt), // WR_DATA_COUNT_WIDTH-bit output: Write Data Count: This bus indicates
// the number of words written into the FIFO.
 
.wr_rst_busy(wr_rst_busy), // 1-bit output: Write Reset Busy: Active-High indicator that the FIFO
// write domain is currently in a reset state.
 
.din(req_fifoi), // WRITE_DATA_WIDTH-bit input: Write Data: The input data bus used when
// writing the FIFO.
 
.injectdbiterr(1'b0), // 1-bit input: Double Bit Error Injection: Injects a double bit error if
// the ECC feature is used on block RAMs or UltraRAM macros.
 
.injectsbiterr(1'b0), // 1-bit input: Single Bit Error Injection: Injects a single bit error if
// the ECC feature is used on block RAMs or UltraRAM macros.
 
.rd_en(rd_fifo & ~rd_rst_busy), // 1-bit input: Read Enable: If the FIFO is not empty, asserting this
// signal causes data (on dout) to be read from the FIFO. Must be held
// active-low when rd_rst_busy is active high.
 
.rst(rst), // 1-bit input: Reset: Must be synchronous to wr_clk. The clock(s) can be
// unstable at the time of applying reset, but reset must be released only
// after the clock(s) is/are stable.
 
.sleep(1'b0), // 1-bit input: Dynamic power saving- If sleep is High, the memory/fifo
// block is in power saving mode.
 
.wr_clk(clk), // 1-bit input: Write clock: Used for write operation. wr_clk must be a
// free running clock.
 
.wr_en(wr_fifo & ~wr_rst_busy) // 1-bit input: Write Enable: If the FIFO is not full, asserting this
// signal causes data (on din) to be written to the FIFO Must be held
// active-low when rst or wr_rst_busy or rd_rst_busy is active high
 
);
 
endmodule
/rtl/mpmc10/mpmc10_mask_select.sv
0,0 → 1,66
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import mpmc10_pkg::*;
 
module mpmc10_mask_select(rst, clk, state, wmask, mask, mask2);
input rst;
input clk;
input [3:0] state;
input [15:0] wmask;
output reg [15:0] mask;
output reg [15:0] mask2;
 
// Setting the data mask. Values are enabled when the data mask is zero.
always_ff @(posedge clk)
if (rst)
mask2 <= 16'h0000;
else begin
if (state==PRESET1)
mask2 <= wmask;
// For RMW cycle all bytes are writtten.
else if (state==WRITE_TRAMP1)
mask2 <= 16'h0000;
end
always_ff @(posedge clk)
if (rst)
mask <= 16'h0000;
else begin
if (state==PRESET2)
mask <= mask2;
end
 
endmodule
/rtl/mpmc10/mpmc10_pkg.sv
0,0 → 1,76
// ============================================================================
// __
// \\__/ o\ (C) 2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
package mpmc10_pkg;
 
parameter CACHE_ASSOC = 4;
 
parameter RMW = 0;
parameter NAR = 2;
parameter AMSB = 28;
parameter TRUE = 1'b1;
parameter FALSE = 1'b0;
parameter CMD_READ = 3'b001;
parameter CMD_WRITE = 3'b000;
// State machine states
parameter IDLE = 4'd0;
parameter PRESET1 = 4'd1;
parameter PRESET2 = 4'd2;
parameter WRITE_DATA0 = 4'd3;
parameter WRITE_DATA1 = 4'd4;
parameter WRITE_DATA2 = 4'd5;
parameter WRITE_DATA3 = 4'd6;
parameter READ_DATA = 4'd7;
parameter READ_DATA0 = 4'd8;
parameter READ_DATA1 = 4'd9;
parameter READ_DATA2 = 4'd10;
parameter WAIT_NACK = 4'd11;
parameter WRITE_TRAMP = 4'd12; // write trampoline
parameter WRITE_TRAMP1 = 4'd13;
parameter PRESET3 = 4'd14;
 
typedef struct packed
{
logic [18:0] tag;
logic modified;
logic [127:0] data;
} mpmc10_cache_line_t;
 
typedef struct packed
{
mpmc10_cache_line_t [CACHE_ASSOC-1:0] lines;
} mpmc10_quad_cache_line_t;
 
endpackage
/rtl/mpmc10/mpmc10_prev_state.sv
0,0 → 1,52
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import mpmc10_pkg::*;
 
module mpmc10_prev_state(clk, state, prev_state);
input clk;
input [3:0] state;
output reg [3:0] prev_state;
 
always_ff @(posedge clk)
if (state==mpmc10_pkg::IDLE) // We can stay in the idle state as long as we like
prev_state <= mpmc10_pkg::IDLE;
else begin
if (state!=prev_state)
prev_state <= state;
end
 
endmodule
/rtl/mpmc10/mpmc10_req_strip_cnt.sv
0,0 → 1,72
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import mpmc10_pkg::*;
 
// Manage memory strip counters.
 
module mpmc10_req_strip_cnt(clk, state, wdf_rdy, rdy, num_strips, strip_cnt);
input clk;
input [3:0] state;
input wdf_rdy;
input rdy;
input [5:0] num_strips;
output reg [5:0] strip_cnt;
 
reg on;
always_ff @(posedge clk)
if (state==IDLE) begin
strip_cnt <= 6'd0;
on <= 1'b0;
end
else begin
if (state==PRESET3)
on <= 1'b1;
if (state==WRITE_DATA0 && wdf_rdy && on) begin
if (strip_cnt != num_strips)
strip_cnt <= strip_cnt + 3'd1;
else
on <= 1'b0;
end
else if (state==READ_DATA1 && rdy && on) begin
if (strip_cnt != num_strips)
strip_cnt <= strip_cnt + 3'd1;
else
on <= 1'b0;
end
end
 
endmodule
/rtl/mpmc10/mpmc10_resp_strip_cnt.sv
0,0 → 1,63
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import mpmc10_pkg::*;
 
module mpmc10_resp_strip_cnt(clk, state, valid, num_strips, strip_cnt);
input clk;
input [3:0] state;
input valid;
input [5:0] num_strips;
output reg [5:0] strip_cnt;
 
reg on;
always_ff @(posedge clk)
if (state==IDLE) begin
strip_cnt <= 6'd0;
on <= 1'b0;
end
else begin
if (state==READ_DATA0)
on <= 1'b1;
if (valid && on) begin
if (strip_cnt != num_strips)
strip_cnt <= strip_cnt + 3'd1;
else
on <= 1'b0;
end
end
 
endmodule
/rtl/mpmc10/mpmc10_resv_bit.sv
0,0 → 1,64
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import mpmc10_pkg::*;
 
// Reservation status bit
module mpmc10_resv_bit(clk, state, wch, we, cr, adr, resv_ch, resv_adr, rb);
input clk;
input [3:0] state;
input we;
input cr;
input [3:0] wch;
input [31:0] adr;
input [3:0] resv_ch [0:mpmc10_pkg::NAR-1];
input [31:0] resv_adr [0:mpmc10_pkg::NAR-1];
output reg rb;
 
integer n5;
always_ff @(posedge clk)
if (state==mpmc10_pkg::IDLE) begin
if (we) begin
if (cr) begin
rb <= mpmc10_pkg::FALSE;
for (n5 = 0; n5 < mpmc10_pkg::NAR; n5 = n5 + 1)
if ((resv_ch[n5]==wch) && (resv_adr[n5][31:5]==adr[31:5]))
rb <= mpmc10_pkg::TRUE;
end
end
end
 
endmodule
/rtl/mpmc10/mpmc10_set_write_mask.sv
0,0 → 1,65
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import mpmc10_pkg::*;
 
module mpmc10_set_write_mask(clk, state, we, sel, adr, mask);
input clk;
input [3:0] state;
input we;
input [31:0] sel;
input [31:0] adr;
output reg [31:0] mask;
 
always_ff @(posedge clk)
tMask(256,we,sel,adr[4:0],mask);
 
task tMask;
input [7:0] widi;
input wei;
input [31:0] seli;
input [4:0] adri;
output [15:0] masko;
begin
if (state==IDLE)
if (wei)
masko <= ~seli >> {adri[4],4'h0};
else
masko <= 16'h0000; // read all bytes
end
endtask
 
endmodule
/rtl/mpmc10/mpmc10_set_write_mask_wb.sv
0,0 → 1,66
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import mpmc10_pkg::*;
 
module mpmc10_set_write_mask_wb(clk, state, we, sel, adr, mask);
parameter WID=16;
input clk;
input [3:0] state;
input we;
input [WID-1:0] sel;
input [31:0] adr;
output reg [WID-1:0] mask;
 
always_ff @(posedge clk)
tMask(256,we,sel,adr[4:0],mask);
 
task tMask;
input [7:0] widi;
input wei;
input [WID-1:0] seli;
input [4:0] adri;
output [15:0] masko;
begin
if (state==IDLE)
if (wei)
masko <= ~seli;
else
masko <= 16'h0000; // read all bytes
end
endtask
 
endmodule
/rtl/mpmc10/mpmc10_state_machine.sv
0,0 → 1,148
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import mpmc10_pkg::*;
 
module mpmc10_state_machine(rst, clk, to, rdy, wdf_rdy, fifo_empty, rd_fifo, fifo_out, state,
num_strips, req_strip_cnt, resp_strip_cnt, rd_data_valid, wway);
input rst;
input clk;
input to; // state machine time-out
input rdy;
input wdf_rdy;
input fifo_empty;
output reg rd_fifo;
input axi_request_readwrite256_t fifo_out;
output reg [3:0] state;
input [5:0] num_strips;
input [5:0] req_strip_cnt;
input [5:0] resp_strip_cnt;
input rd_data_valid;
output reg [1:0] wway;
 
reg [3:0] next_state;
reg next_rd_fifo;
 
always_ff @(posedge clk)
state <= next_state;
always_ff @(posedge clk)
rd_fifo <= next_rd_fifo;
always_ff @(posedge clk)
if (rst)
wway <= 2'd0;
else begin
if (state==PRESET1)
wway <= wway + 2'd1;
end
 
always_comb
if (rst) begin
next_state <= IDLE;
next_rd_fifo <= 1'b0;
end
else begin
next_rd_fifo <= 1'b0;
case(state)
IDLE:
begin
if (!fifo_empty) begin
next_rd_fifo <= 1'b1;
next_state <= PRESET1;
end
end
PRESET1:
next_state <= PRESET2;
PRESET2:
next_state <= PRESET3;
PRESET3:
if (fifo_out.write.WVALID)
next_state <= WRITE_DATA0;
else
next_state <= READ_DATA0;
// Write data to the data fifo
// Write occurs when app_wdf_wren is true and app_wdf_rdy is true
WRITE_DATA0:
// Issue a write command if the fifo is full.
// if (!app_wdf_rdy)
// next_state <= WRITE_DATA1;
// else
if (wdf_rdy)// && req_strip_cnt==num_strips)
next_state <= WRITE_DATA1;
else
next_state <= WRITE_DATA0;
WRITE_DATA1:
next_state <= WRITE_DATA2;
WRITE_DATA2:
if (rdy)
next_state <= WRITE_DATA3;
else
next_state <= WRITE_DATA2;
WRITE_DATA3:
next_state <= IDLE;
 
// There could be multiple read requests submitted before any response occurs.
// Stay in the SET_CMD_RD until all requested strips have been processed.
READ_DATA0:
next_state <= READ_DATA1;
// Could it take so long to do the request that we start getting responses
// back?
READ_DATA1:
if (rdy && req_strip_cnt==num_strips)
next_state <= READ_DATA2;
else
next_state <= READ_DATA1;
// Wait for incoming responses, but only for so long to prevent a hang.
READ_DATA2:
if (rd_data_valid && resp_strip_cnt==num_strips)
next_state <= WAIT_NACK;
else
next_state <= READ_DATA2;
 
WAIT_NACK:
// If we're not seeing a nack and there is a channel selected, then the
// cache tag must not have updated correctly.
// For writes, assume a nack by now.
next_state <= IDLE;
default: next_state <= IDLE;
endcase
 
// Is the state machine hung?
if (to)
next_state <= IDLE;
end
 
endmodule
/rtl/mpmc10/mpmc10_state_machine_wb.sv
0,0 → 1,150
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import mpmc10_pkg::*;
 
module mpmc10_state_machine_wb(rst, clk, to, rdy, wdf_rdy, fifo_empty, rd_fifo,
rd_rst_busy, fifo_out, state,
num_strips, req_strip_cnt, resp_strip_cnt, rd_data_valid, wway);
input rst;
input clk;
input to; // state machine time-out
input rdy;
input wdf_rdy;
input fifo_empty;
input rd_rst_busy;
output reg rd_fifo;
input wb_write_request128_t fifo_out;
output reg [3:0] state;
input [5:0] num_strips;
input [5:0] req_strip_cnt;
input [5:0] resp_strip_cnt;
input rd_data_valid;
output reg [1:0] wway;
 
reg [3:0] next_state;
reg next_rd_fifo;
 
always_ff @(posedge clk)
state <= next_state;
always_ff @(posedge clk)
rd_fifo <= next_rd_fifo;
always_ff @(posedge clk)
if (rst)
wway <= 2'd0;
else begin
if (state==mpmc10_pkg::PRESET1)
wway <= wway + 2'd1;
end
 
always_comb
if (rst) begin
next_state <= mpmc10_pkg::IDLE;
next_rd_fifo <= 1'b0;
end
else begin
next_rd_fifo <= 1'b0;
case(state)
mpmc10_pkg::IDLE:
if (!fifo_empty && !rd_rst_busy) begin
next_rd_fifo <= 1'b1;
next_state <= mpmc10_pkg::PRESET1;
end
else
next_state <= mpmc10_pkg::IDLE;
mpmc10_pkg::PRESET1:
next_state <= mpmc10_pkg::PRESET2;
mpmc10_pkg::PRESET2:
next_state <= mpmc10_pkg::PRESET3;
mpmc10_pkg::PRESET3:
if (fifo_out.stb & fifo_out.we)
next_state <= mpmc10_pkg::WRITE_DATA0;
else
next_state <= mpmc10_pkg::READ_DATA0;
// Write data to the data fifo
// Write occurs when app_wdf_wren is true and app_wdf_rdy is true
mpmc10_pkg::WRITE_DATA0:
// Issue a write command if the fifo is full.
// if (!app_wdf_rdy)
// next_state <= WRITE_DATA1;
// else
if (wdf_rdy)// && req_strip_cnt==num_strips)
next_state <= mpmc10_pkg::WRITE_DATA1;
else
next_state <= mpmc10_pkg::WRITE_DATA0;
mpmc10_pkg::WRITE_DATA1:
next_state <= mpmc10_pkg::WRITE_DATA2;
mpmc10_pkg::WRITE_DATA2:
if (rdy)
next_state <= mpmc10_pkg::WRITE_DATA3;
else
next_state <= mpmc10_pkg::WRITE_DATA2;
mpmc10_pkg::WRITE_DATA3:
next_state <= mpmc10_pkg::IDLE;
 
// There could be multiple read requests submitted before any response occurs.
// Stay in the SET_CMD_RD until all requested strips have been processed.
mpmc10_pkg::READ_DATA0:
next_state <= mpmc10_pkg::READ_DATA1;
// Could it take so long to do the request that we start getting responses
// back?
mpmc10_pkg::READ_DATA1:
if (rdy && req_strip_cnt==num_strips)
next_state <= mpmc10_pkg::READ_DATA2;
else
next_state <= mpmc10_pkg::READ_DATA1;
// Wait for incoming responses, but only for so long to prevent a hang.
mpmc10_pkg::READ_DATA2:
if (rd_data_valid && resp_strip_cnt==num_strips)
next_state <= mpmc10_pkg::WAIT_NACK;
else
next_state <= mpmc10_pkg::READ_DATA2;
 
mpmc10_pkg::WAIT_NACK:
// If we're not seeing a nack and there is a channel selected, then the
// cache tag must not have updated correctly.
// For writes, assume a nack by now.
next_state <= mpmc10_pkg::IDLE;
default: next_state <= mpmc10_pkg::IDLE;
endcase
 
// Is the state machine hung?
// if (to)
// next_state <= mpmc10_pkg::IDLE;
end
 
endmodule
/rtl/mpmc10/mpmc10_sync.sv
0,0 → 1,50
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import mpmc10_pkg::*;
 
module mpmc10_sync(clk, i, o);
parameter WID=128;
input clk;
input [WID-1:0] i;
output reg [WID-1:0] o;
 
always_ff @(posedge clk)
begin
o <= i;
end
 
endmodule
/rtl/mpmc10/mpmc10_sync128_wb.sv
0,0 → 1,50
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import wishbone_pkg::*;
import mpmc10_pkg::*;
 
module mpmc10_sync128_wb(clk, i, o);
input clk;
input wb_write_request128_t i;
output wb_write_request128_t o;
 
always_ff @(posedge clk)
begin
o <= i;
end
 
endmodule
/rtl/mpmc10/mpmc10_sync256_wb.sv
0,0 → 1,50
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import wishbone_pkg::*;
import mpmc10_pkg::*;
 
module mpmc10_sync256_wb(clk, i, o);
input clk;
input wb_write_request256_t i;
output wb_write_request256_t o;
 
always_ff @(posedge clk)
begin
o <= i;
end
 
endmodule
/rtl/mpmc10/mpmc10_to_cnt.sv
0,0 → 1,57
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// ============================================================================
//
import mpmc10_pkg::*;
 
module mpmc10_to_cnt(clk, state, prev_state, to_cnt);
input clk;
input [3:0] state;
input [3:0] prev_state;
output reg [15:0] to_cnt;
 
always_ff @(posedge clk)
if (state==mpmc10_pkg::IDLE) begin // We can stay in the idle state as long as we like
to_cnt <= 'd0;
end
else begin
if (state==prev_state) begin
to_cnt <= to_cnt+2'd1;
if (to_cnt[9])
to_cnt <= 'd0;
end
end
 
endmodule
/rtl/mpmc10/mpmc10_waddr_gen.sv
0,0 → 1,73
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// A bit of a misnomer. This is the address used to load the cache, it is the
// cache write address. The cache is loaded via memory read cycles not memory
// write cycles.
// ============================================================================
//
import mpmc10_pkg::*;
 
module mpmc10_waddr_gen(rst, clk, state, valid, num_strips, strip_cnt, addr_base, addr);
input rst;
input clk;
input [3:0] state;
input valid;
input [5:0] num_strips;
input [5:0] strip_cnt;
input [31:0] addr_base;
output reg [31:0] addr;
 
reg on; // Used to ignore extra data
 
always_ff @(posedge clk)
if (rst) begin
addr <= 32'h1FFFFFFF;
on <= 1'b0;
end
else begin
if (state==READ_DATA0)
on <= 1'b1;
if (strip_cnt == num_strips && valid)
on <= 1'b0;
if (state==PRESET2)
addr <= {addr_base[31:4],4'h0};
else if (valid && strip_cnt != num_strips && on)
addr[31:4] <= addr[31:4] + 2'd1;
// Increment the address if we had to start a new burst.
// else if (state==WRITE_DATA3 && req_strip_cnt!=num_strips)
// app_addr <= app_addr + {req_strip_cnt,4'h0}; // works for only 1 missed burst
end
 
endmodule
/rtl/mpmc10/mpmc10_wb.sv
0,0 → 1,877
`timescale 1ns / 1ps
// ============================================================================
// __
// \\__/ o\ (C) 2015-2022 Robert Finch, Waterloo
// \ __ / All rights reserved.
// \/_// robfinch<remove>@finitron.ca
// ||
//
// BSD 3-Clause License
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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 THE COPYRIGHT HOLDER OR CONTRIBUTORS 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.
//
// 16000 LUTs, 130 BRAM (64kB cache)
//
// Read channels always wait until there is valid data in the cache.
// ============================================================================
//
//`define RED_SCREEN 1'b1
 
import wishbone_pkg::*;
import mpmc10_pkg::*;
 
module mpmc10_wb(
input rst,
input clk100MHz,
input mem_ui_rst,
input mem_ui_clk,
output reg rstn,
output [31:0] app_waddr,
input app_rdy,
output app_en,
output [2:0] app_cmd,
output [28:0] app_addr,
input app_rd_data_valid,
output [15:0] app_wdf_mask,
output reg [127:0] app_wdf_data,
input app_wdf_rdy,
output app_wdf_wren,
output app_wdf_end,
input [127:0] app_rd_data,
input app_rd_data_end,
input ch0clk, ch1clk, ch2clk, ch3clk, ch4clk, ch5clk, ch6clk, ch7clk,
input wb_write_request128_t ch0i,
output wb_read_response128_t ch0o,
input wb_write_request128_t ch1i,
output wb_read_response128_t ch1o,
input wb_write_request128_t ch2i,
output wb_read_response128_t ch2o,
input wb_write_request128_t ch3i,
output wb_read_response128_t ch3o,
input wb_write_request128_t ch4i,
output wb_read_response128_t ch4o,
input wb_write_request128_t ch5i,
output wb_read_response128_t ch5o,
input wb_write_request128_t ch6i,
output wb_read_response128_t ch6o,
input wb_write_request128_t ch7i,
output wb_read_response128_t ch7o,
output [3:0] state
);
parameter NAR = 2; // Number of address reservations
parameter CL = 3'd4; // Cache read latency
parameter STREAM0 = TRUE;
parameter STREAM1 = FALSE;
parameter STREAM2 = FALSE;
parameter STREAM3 = FALSE;
parameter STREAM4 = FALSE;
parameter STREAM5 = TRUE;
parameter STREAM6 = FALSE;
parameter STREAM7 = FALSE;
 
wb_write_request128_t ch0is;
wb_write_request128_t ch0is2;
wb_write_request128_t ch1is;
wb_write_request128_t ch1is2;
wb_write_request128_t ch2is;
wb_write_request128_t ch2is2;
wb_write_request128_t ch3is;
wb_write_request128_t ch3is2;
wb_write_request128_t ch4is;
wb_write_request128_t ch4is2;
wb_write_request128_t ch5is;
wb_write_request128_t ch5is2;
wb_write_request128_t ch6is;
wb_write_request128_t ch6is2;
wb_write_request128_t ch7is;
wb_write_request128_t ch7is2;
 
wb_read_response128_t ch0oa, ch0ob;
wb_read_response128_t ch1oa, ch1ob;
wb_read_response128_t ch2oa, ch2ob;
wb_read_response128_t ch3oa, ch3ob;
wb_read_response128_t ch4oa, ch4ob;
wb_read_response128_t ch5oa, ch5ob;
wb_read_response128_t ch6oa, ch6ob;
wb_read_response128_t ch7oa, ch7ob;
 
assign ch0o = STREAM0 ? ch0ob : ch0oa;
assign ch1o = STREAM1 ? ch1ob : ch1oa;
assign ch2o = STREAM2 ? ch2ob : ch2oa;
assign ch3o = STREAM3 ? ch3ob : ch3oa;
assign ch4o = STREAM4 ? ch4ob : ch4oa;
assign ch5o = STREAM5 ? ch5ob : ch5oa;
assign ch6o = STREAM6 ? ch6ob : ch6oa;
assign ch7o = STREAM7 ? ch7ob : ch7oa;
 
wb_write_request128_t req_fifoi;
wb_write_request128_t req_fifoo;
wb_write_request128_t ld;
 
genvar g;
integer n1,n2;
wire almost_full;
wire [4:0] cnt;
reg wr_fifo;
wire [3:0] prev_state;
wire [3:0] state;
wire rd_fifo; // from state machine
reg [5:0] num_strips; // from fifo
wire [5:0] req_strip_cnt;
wire [5:0] resp_strip_cnt;
wire [15:0] tocnt;
wire [31:0] app_waddr;
reg [31:0] adr;
reg [3:0] uch; // update channel
wire [15:0] wmask;
wire [15:0] mem_wdf_mask2;
reg [127:0] dat128;
wire [255:0] dat256;
wire [3:0] resv_ch [0:NAR-1];
wire [31:0] resv_adr [0:NAR-1];
wire rb1;
reg [7:0] req;
wire [1:0] wway;
reg [127:0] rd_data_r;
reg rd_data_valid_r;
 
wire ch0_hit_s, ch1_hit_s, ch2_hit_s, ch3_hit_s;
wire ch4_hit_s, ch5_hit_s, ch6_hit_s, ch7_hit_s;
wire ch0_hit_ne, ch5_hit_ne;
 
always_ff @(posedge mem_ui_clk)
rd_data_r <= app_rd_data;
always_ff @(posedge mem_ui_clk)
rd_data_valid_r <= app_rd_data_valid;
 
reg [19:0] rst_ctr;
always @(posedge clk100MHz)
if (rst)
rst_ctr <= 24'd0;
else begin
if (!rst_ctr[15])
rst_ctr <= rst_ctr + 2'd1;
rstn <= rst_ctr[15];
end
 
reg [7:0] stb [0:7];
always_comb stb[0] = ch0is.stb;
always_comb stb[1] = ch1is.stb;
always_comb stb[2] = ch2is.stb;
always_comb stb[3] = ch3is.stb;
always_comb stb[4] = ch4is.stb;
always_comb stb[5] = ch5is.stb;
always_comb stb[6] = ch6is.stb;
always_comb stb[7] = ch7is.stb;
 
reg [2:0] chcnt [0:7];
always_ff @(posedge mem_ui_clk)
if (rst) begin
for (n2 = 0; n2 < 8; n2 = n2 + 1)
chcnt[n2] <= 'd0;
end
else begin
for (n2 = 0; n2 < 8; n2 = n2 + 1)
if (stb[n2]) begin
if (chcnt[n2] < CL)
chcnt[n2] <= chcnt[n2] + 2'd1;
end
else
chcnt[n2] <= 'd0;
end
 
reg [7:0] pe_req;
reg [7:0] chack;
always_comb chack[0] = ch0o.ack;
always_comb chack[1] = ch1o.ack;
always_comb chack[2] = ch2o.ack;
always_comb chack[3] = ch3o.ack;
always_comb chack[4] = ch4o.ack;
always_comb chack[5] = ch5o.ack;
always_comb chack[6] = ch6o.ack;
always_comb chack[7] = ch7o.ack;
 
edge_det edch0 (
.rst(mem_ui_rst),
.clk(mem_ui_clk),
.ce(1'b1),
.i((!ch0o.ack && ch0is.stb && !ch0is.we && chcnt[0]==CL) || (ch0is.we && ch0is.stb)),
.pe(pe_req[0]),
.ne(),
.ee()
);
edge_det edch1 (
.rst(mem_ui_rst),
.clk(mem_ui_clk),
.ce(1'b1),
.i((!ch1o.ack && ch1is.stb && !ch1is.we && chcnt[1]==CL) || (ch1is.we && ch1is.stb)),
.pe(pe_req[1]),
.ne(),
.ee()
);
edge_det edch2 (
.rst(mem_ui_rst),
.clk(mem_ui_clk),
.ce(1'b1),
.i((!ch2o.ack && ch2is.stb && !ch2is.we && chcnt[2]==CL) || (ch2is.we && ch2is.stb)),
.pe(pe_req[2]),
.ne(),
.ee()
);
edge_det edch3 (
.rst(mem_ui_rst),
.clk(mem_ui_clk),
.ce(1'b1),
.i((!ch3o.ack && ch3is.stb && !ch3is.we && chcnt[3]==CL) || (ch3is.we && ch3is.stb)),
.pe(pe_req[3]),
.ne(),
.ee()
);
edge_det edch4 (
.rst(mem_ui_rst),
.clk(mem_ui_clk),
.ce(1'b1),
.i((!ch4o.ack && ch4is.stb && !ch4is.we && chcnt[4]==CL) || (ch4is.we && ch4is.stb)),
.pe(pe_req[4]),
.ne(),
.ee()
);
edge_det edch5 (
.rst(mem_ui_rst),
.clk(mem_ui_clk),
.ce(1'b1),
.i((!ch5_hit_s && ch5is.stb && !ch5is.we && chcnt[5]==CL) || (ch5is.we && ch5is.stb)),
.pe(pe_req[5]),
.ne(),
.ee()
);
edge_det edch6 (
.rst(mem_ui_rst),
.clk(mem_ui_clk),
.ce(1'b1),
.i((!ch6o.ack && ch6is.stb && !ch6is.we && chcnt[6]==CL) || (ch6is.we && ch6is.stb)),
.pe(pe_req[6]),
.ne(),
.ee()
);
edge_det edch7 (
.rst(mem_ui_rst),
.clk(mem_ui_clk),
.ce(1'b1),
.i((!ch7o.ack && ch7is.stb && !ch7is.we && chcnt[7]==CL) || (ch7is.we && ch7is.stb)),
.pe(pe_req[7]),
.ne(),
.ee()
);
wire [3:0] req_sel;
generate begin : gReq
for (g = 0; g < 8; g = g + 1)
always_ff @(posedge mem_ui_clk)
if (pe_req[g])
req[g] <= 1'b1;
else if (req_sel==g[3:0] || chack[g])
req[g] <= 1'b0;
end
endgenerate
 
// Register signals onto mem_ui_clk domain
mpmc10_sync128_wb usyn0
(
.clk(mem_ui_clk),
.i(ch0i),
.o(ch0is)
);
mpmc10_sync128_wb usyn1
(
.clk(mem_ui_clk),
.i(ch1i),
.o(ch1is)
);
mpmc10_sync128_wb usyn2
(
.clk(mem_ui_clk),
.i(ch2i),
.o(ch2is)
);
mpmc10_sync128_wb usyn3
(
.clk(mem_ui_clk),
.i(ch3i),
.o(ch3is)
);
mpmc10_sync128_wb usyn4
(
.clk(mem_ui_clk),
.i(ch4i),
.o(ch4is)
);
mpmc10_sync128_wb usyn5
(
.clk(mem_ui_clk),
.i(ch5i),
.o(ch5is)
);
mpmc10_sync128_wb usyn6
(
.clk(mem_ui_clk),
.i(ch6i),
.o(ch6is)
);
mpmc10_sync128_wb usyn7
(
.clk(mem_ui_clk),
.i(ch7i),
.o(ch7is)
);
 
// Streaming channels have a burst length of 64. Round the address to the burst
// length.
always_comb
begin
ch0is2 <= ch0is;
ch0is2.adr <= {ch0is.adr[31:10],10'b0};
end
always_comb
begin
ch1is2 <= ch1is;
ch1is2.adr <= {ch1is.adr[31:10],10'b0};
end
always_comb
begin
ch2is2 <= ch2is;
ch2is2.adr <= {ch2is.adr[31:10],10'b0};
end
always_comb
begin
ch3is2 <= ch3is;
ch3is2.adr <= {ch3is.adr[31:10],10'b0};
end
always_comb
begin
ch4is2 <= ch4is;
ch4is2.adr <= {ch4is.adr[31:10],10'b0};
end
always_comb
begin
ch5is2 <= ch5is;
ch5is2.adr <= {ch5is.adr[31:10],10'b0};
end
always_comb
begin
ch6is2 <= ch6is;
ch6is2.adr <= {ch6is.adr[31:10],10'b0};
end
always_comb
begin
ch7is2 <= ch7is;
ch7is2.adr <= {ch7is.adr[31:10],10'b0};
end
 
always_comb
begin
ld.bte <= wishbone_pkg::LINEAR;
ld.cti <= wishbone_pkg::CLASSIC;
ld.blen <= 'd0;
ld.cyc <= req_fifoo.stb && !req_fifoo.we && rd_data_valid_r && (uch!=4'd0 && uch!=4'd5);
ld.stb <= req_fifoo.stb && !req_fifoo.we && rd_data_valid_r && (uch!=4'd0 && uch!=4'd5);
ld.we <= 1'b0;
ld.adr <= {app_waddr[31:4],4'h0};
ld.dat <= {app_waddr[31:14],8'h00,rd_data_r}; // modified=false,tag = high order address bits
ld.sel <= {36{1'b1}}; // update all bytes
end
 
reg ch0wack;
reg ch1wack;
reg ch2wack;
reg ch3wack;
reg ch4wack;
reg ch5wack;
reg ch6wack;
reg ch7wack;
 
always_ff @(posedge mem_ui_clk)
begin
if (!ch0i.stb) ch0wack <= 1'b0;
if (!ch1i.stb) ch1wack <= 1'b0;
if (!ch2i.stb) ch2wack <= 1'b0;
if (!ch3i.stb) ch3wack <= 1'b0;
if (!ch4i.stb) ch4wack <= 1'b0;
if (!ch5i.stb) ch5wack <= 1'b0;
if (!ch6i.stb) ch6wack <= 1'b0;
if (!ch7i.stb) ch7wack <= 1'b0;
if (state==WRITE_DATA3)
case(uch)
4'd0: ch0wack <= 1'b1;
4'd1: ch1wack <= 1'b1;
4'd2: ch2wack <= 1'b1;
4'd3: ch3wack <= 1'b1;
4'd4: ch4wack <= 1'b1;
4'd5: ch5wack <= 1'b1;
4'd6: ch6wack <= 1'b1;
4'd7: ch7wack <= 1'b1;
default: ;
endcase
end
 
mpmc10_cache_wb ucache1
(
.rst(mem_ui_rst),
.wclk(mem_ui_clk),
.inv(),
.wchi(req_fifoo),
.wcho(),
.ld(ld),
.ch0clk(STREAM0 ? 1'b0 : ch0clk),
.ch1clk(STREAM1 ? 1'b0 : ch1clk),
.ch2clk(STREAM2 ? 1'b0 : ch2clk),
.ch3clk(STREAM3 ? 1'b0 : ch3clk),
.ch4clk(STREAM4 ? 1'b0 : ch4clk),
.ch5clk(STREAM5 ? 1'b0 : ch5clk),
.ch6clk(STREAM6 ? 1'b0 : ch6clk),
.ch7clk(STREAM7 ? 1'b0 : ch7clk),
.ch0i(STREAM0 ? 'd0 : ch0is),
.ch1i(STREAM1 ? 'd0 : ch1is),
.ch2i(STREAM2 ? 'd0 : ch2is),
.ch3i(STREAM3 ? 'd0 : ch3is),
.ch4i(STREAM4 ? 'd0 : ch4is),
.ch5i(STREAM5 ? 'd0 : ch5is),
.ch6i(STREAM6 ? 'd0 : ch6is),
.ch7i(STREAM7 ? 'd0 : ch7is),
.ch0wack(ch0wack),
.ch1wack(ch1wack),
.ch2wack(ch2wack),
.ch3wack(ch3wack),
.ch4wack(ch4wack),
.ch5wack(ch5wack),
.ch6wack(ch6wack),
.ch7wack(ch7wack),
.ch0o(ch0oa),
.ch1o(ch1oa),
.ch2o(ch2oa),
.ch3o(ch3oa),
.ch4o(ch4oa),
.ch5o(ch5oa),
.ch6o(ch6oa),
.ch7o(ch7oa)
);
 
mpmc10_strm_read_cache ustrm0
(
.rst(rst),
.wclk(mem_ui_clk),
.wr(uch==4'd0 && rd_data_valid_r),
.wadr({app_waddr[31:4],4'h0}),
.wdat(rd_data_r),
// .inv(1'b0),
.rclk(mem_ui_clk),
.rd(ch0is.stb & ~ch0is.we),
.radr({ch0is.adr[31:4],4'h0}),
.rdat(ch0ob.dat),
.hit(ch0_hit_s)
);
 
mpmc10_strm_read_cache ustrm1
(
.rst(rst),
.wclk(mem_ui_clk),
.wr(uch==4'd1 && rd_data_valid_r),
.wadr({app_waddr[31:4],4'h0}),
.wdat(rd_data_r),
// .inv(1'b0),
.rclk(mem_ui_clk),
.rd(ch1is.stb & ~ch1is.we),
.radr({ch1is.adr[31:4],4'h0}),
.rdat(ch1ob.dat),
.hit(ch1_hit_s)
);
 
mpmc10_strm_read_cache ustrm2
(
.rst(rst),
.wclk(mem_ui_clk),
.wr(uch==4'd2 && rd_data_valid_r),
.wadr({app_waddr[31:4],4'h0}),
.wdat(rd_data_r),
// .inv(1'b0),
.rclk(mem_ui_clk),
.rd(ch2is.stb & ~ch2is.we),
.radr({ch2is.adr[31:4],4'h0}),
.rdat(ch2ob.dat),
.hit(ch2_hit_s)
);
 
mpmc10_strm_read_cache ustrm3
(
.rst(rst),
.wclk(mem_ui_clk),
.wr(uch==4'd3 && rd_data_valid_r),
.wadr({app_waddr[31:4],4'h0}),
.wdat(rd_data_r),
// .inv(1'b0),
.rclk(mem_ui_clk),
.rd(ch3is.stb & ~ch3is.we),
.radr({ch3is.adr[31:4],4'h0}),
.rdat(ch3ob.dat),
.hit(ch3_hit_s)
);
 
mpmc10_strm_read_cache ustrm4
(
.rst(rst),
.wclk(mem_ui_clk),
.wr(uch==4'd4 && rd_data_valid_r),
.wadr({app_waddr[31:4],4'h0}),
.wdat(rd_data_r),
// .inv(1'b0),
.rclk(mem_ui_clk),
.rd(ch4is.stb & ~ch4is.we),
.radr({ch4is.adr[31:4],4'h0}),
.rdat(ch4ob.dat),
.hit(ch4_hit_s)
);
 
mpmc10_strm_read_cache ustrm5
(
.rst(rst),
.wclk(mem_ui_clk),
.wr(uch==4'd5 && rd_data_valid_r),
.wadr({app_waddr[31:4],4'h0}),
.wdat(rd_data_r),
// .inv(1'b0),
.rclk(mem_ui_clk),
.rd(ch5is.stb & ~ch5is.we),
.radr({ch5is.adr[31:4],4'h0}),
.rdat(ch5ob.dat),
.hit(ch5_hit_s)
);
 
mpmc10_strm_read_cache ustrm6
(
.rst(rst),
.wclk(mem_ui_clk),
.wr(uch==4'd6 && rd_data_valid_r),
.wadr({app_waddr[31:4],4'h0}),
.wdat(rd_data_r),
// .inv(1'b0),
.rclk(mem_ui_clk),
.rd(ch6is.stb & ~ch6is.we),
.radr({ch6is.adr[31:4],4'h0}),
.rdat(ch6ob.dat),
.hit(ch6_hit_s)
);
 
mpmc10_strm_read_cache ustrm7
(
.rst(rst),
.wclk(mem_ui_clk),
.wr(uch==4'd7 && rd_data_valid_r),
.wadr({app_waddr[31:4],4'h0}),
.wdat(rd_data_r),
// .inv(1'b0),
.rclk(mem_ui_clk),
.rd(ch7is.stb & ~ch7is.we),
.radr({ch7is.adr[31:4],4'h0}),
.rdat(ch7ob.dat),
.hit(ch7_hit_s)
);
 
always_comb ch0ob.ack = ch0_hit_s & ch0i.stb;
always_comb ch1ob.ack = ch1_hit_s & ch1i.stb;
always_comb ch2ob.ack = ch2_hit_s & ch2i.stb;
always_comb ch3ob.ack = ch3_hit_s & ch3i.stb;
always_comb ch4ob.ack = ch4_hit_s & ch4i.stb;
always_comb ch5ob.ack = ch5_hit_s & ch5i.stb;
always_comb ch6ob.ack = ch6_hit_s & ch6i.stb;
always_comb ch7ob.ack = ch7_hit_s & ch7i.stb;
 
wire [7:0] sel;
wire rd_rst_busy;
wire wr_rst_busy;
wire cd_sel;
change_det #(.WID(8)) ucdsel (.rst(rst), .clk(mem_ui_clk), .i(sel), .cd(cd_sel));
 
always_comb //ff @(posedge mem_ui_clk)
wr_fifo = |sel & ~almost_full & ~wr_rst_busy & cd_sel;
 
roundRobin rr1
(
.rst(rst),
.clk(mem_ui_clk),
.ce(1'b1),//~|req || chack[req_sel]),
.req(req),
.lock(8'h00),
.sel(sel),
.sel_enc(req_sel)
);
 
always_comb
case(req_sel)
4'd0: req_fifoi <= STREAM0 ? ch0is2 : ch0is;
4'd1: req_fifoi <= STREAM1 ? ch1is2 : ch1is;
4'd2: req_fifoi <= STREAM2 ? ch2is2 : ch2is;
4'd3: req_fifoi <= STREAM3 ? ch3is2 : ch3is;
4'd4: req_fifoi <= STREAM4 ? ch4is2 : ch4is;
4'd5: req_fifoi <= STREAM5 ? ch5is2 : ch5is;
4'd6: req_fifoi <= STREAM6 ? ch6is2 : ch6is;
4'd7: req_fifoi <= STREAM7 ? ch7is2 : ch7is;
default: req_fifoi <= 'd0;
endcase
 
mpmc10_fifo ufifo1
(
.rst(rst),
.clk(mem_ui_clk),
.rd_fifo(rd_fifo),
.wr_fifo(wr_fifo),
.req_fifoi(req_fifoi),
.req_fifoo(req_fifoo),
.v(v),
.full(full),
.empty(empty),
.almost_full(almost_full),
.rd_rst_busy(rd_rst_busy),
.wr_rst_busy(wr_rst_busy),
.cnt(cnt)
);
 
always_comb
uch <= req_fifoo.cid;
always_comb
num_strips <= req_fifoo.blen;
always_comb
adr <= req_fifoo.adr;
 
wire [2:0] app_addr3; // dummy to make up 32-bits
 
mpmc10_addr_gen uag1
(
.rst(mem_ui_rst),
.clk(mem_ui_clk),
.state(state),
.rdy(app_rdy),
.num_strips(num_strips),
.strip_cnt(req_strip_cnt),
.addr_base(adr),
.addr({app_addr3,app_addr})
);
 
mpmc10_waddr_gen uwag1
(
.rst(mem_ui_rst),
.clk(mem_ui_clk),
.state(state),
.valid(rd_data_valid_r),
.num_strips(num_strips),
.strip_cnt(resp_strip_cnt),
.addr_base(adr),
.addr(app_waddr)
);
 
mpmc10_set_write_mask_wb uswm1
(
.clk(mem_ui_clk),
.state(state),
.we(req_fifoo.we),
.sel(req_fifoo.sel[15:0]),
.adr(adr|{req_strip_cnt[0],4'h0}),
.mask(wmask)
);
 
mpmc10_mask_select unsks1
(
.rst(mem_ui_rst),
.clk(mem_ui_clk),
.state(state),
.wmask(wmask),
.mask(app_wdf_mask),
.mask2(mem_wdf_mask2)
);
 
mpmc10_data_select #(.WID(128)) uds1
(
.clk(mem_ui_clk),
.state(state),
.dati(req_fifoo.dat),
.dato(dat256)
);
 
always_comb
dat128 <= dat256;//req_strip_cnt[0] ? dat256[255:128] : dat256[127:0];
 
// Setting the data value. Unlike reads there is only a single strip involved.
// Force unselected byte lanes to $FF
reg [127:0] dat128x;
generate begin
for (g = 0; g < 16; g = g + 1)
always_comb
if (mem_wdf_mask2[g])
dat128x[g*8+7:g*8] = 8'hFF;
else
dat128x[g*8+7:g*8] = dat128[g*8+7:g*8];
end
endgenerate
 
always_ff @(posedge mem_ui_clk)
if (mem_ui_rst)
app_wdf_data <= 128'd0;
else begin
if (state==PRESET2)
app_wdf_data <= dat128x;
// else if (state==WRITE_TRAMP1)
// app_wdf_data <= rmw_data;
end
 
 
mpmc10_state_machine_wb usm1
(
.rst(rst|mem_ui_rst),
.clk(mem_ui_clk),
.to(tocnt[9]),
.rdy(app_rdy),
.wdf_rdy(app_wdf_rdy),
.fifo_empty(empty),
.rd_rst_busy(rd_rst_busy),
.rd_fifo(rd_fifo),
.fifo_out(req_fifoo),
.state(state),
.num_strips(num_strips),
.req_strip_cnt(req_strip_cnt),
.resp_strip_cnt(resp_strip_cnt),
.rd_data_valid(rd_data_valid_r)
);
 
mpmc10_to_cnt utoc1
(
.clk(mem_ui_clk),
.state(state),
.prev_state(prev_state),
.to_cnt(tocnt)
);
 
mpmc10_prev_state upst1
(
.clk(mem_ui_clk),
.state(state),
.prev_state(prev_state)
);
 
mpmc10_app_en_gen ueng1
(
.clk(mem_ui_clk),
.state(state),
.rdy(app_rdy),
.strip_cnt(req_strip_cnt),
.num_strips(num_strips),
.en(app_en)
);
 
mpmc10_app_cmd_gen ucg1
(
.clk(mem_ui_clk),
.state(state),
.cmd(app_cmd)
);
 
mpmc10_app_wdf_wren_gen uwreng1
(
.clk(mem_ui_clk),
.state(state),
.rdy(app_wdf_rdy),
.wren(app_wdf_wren)
);
 
mpmc10_app_wdf_end_gen uwendg1
(
.clk(mem_ui_clk),
.state(state),
.rdy(app_wdf_rdy),
.strip_cnt(req_strip_cnt),
.num_strips(num_strips),
.wend(app_wdf_end)
);
 
mpmc10_req_strip_cnt ursc1
(
.clk(mem_ui_clk),
.state(state),
.wdf_rdy(app_wdf_rdy),
.rdy(app_rdy),
.num_strips(num_strips),
.strip_cnt(req_strip_cnt)
);
 
mpmc10_resp_strip_cnt urespsc1
(
.clk(mem_ui_clk),
.state(state),
.valid(rd_data_valid_r),
.num_strips(num_strips),
.strip_cnt(resp_strip_cnt)
);
 
// Reservation status bit
mpmc10_resv_bit ursb1
(
.clk(mem_ui_clk),
.state(state),
.wch(req_fifoo.cid),
.we(req_fifoo.stb & req_fifoo.we),
.cr(req_fifoo.csr & req_fifoo.we),
.adr(req_fifoo.adr),
.resv_ch(resv_ch),
.resv_adr(resv_adr),
.rb(rb1)
);
 
mpmc10_addr_resv_man #(.NAR(NAR)) ursvm1
(
.rst(mem_ui_rst),
.clk(mem_ui_clk),
.state(state),
.adr0(32'h0),
.adr1(ch1is.adr),
.adr2(ch2is.adr),
.adr3(ch3is.adr),
.adr4(ch4is.adr),
.adr5(32'h0),
.adr6(ch6is.adr),
.adr7(ch7is.adr),
.sr0(1'b0),
.sr1(ch1is.csr & ch1is.stb & ~ch1is.we),
.sr2(ch2is.csr & ch2is.stb & ~ch2is.we),
.sr3(ch3is.csr & ch3is.stb & ~ch3is.we),
.sr4(ch4is.csr & ch4is.stb & ~ch4is.we),
.sr5(1'b0),
.sr6(ch6is.csr & ch6is.stb & ~ch6is.we),
.sr7(ch7is.csr & ch7is.stb & ~ch7is.we),
.wch(req_fifoo.stb ? req_fifoo.cid : 4'd15),
.we(req_fifoo.stb & req_fifoo.we),
.wadr(req_fifoo.adr),
.cr(req_fifoo.csr & req_fifoo.stb & req_fifoo.we),
.resv_ch(resv_ch),
.resv_adr(resv_adr)
);
 
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.