manta/test/functional_sim/logic_analyzer_tb/sample_mem.v

116 lines
2.8 KiB
Verilog

`default_nettype none
`timescale 1ns/1ps
module sample_mem(
input wire clk,
// fifo
input wire acquire,
input wire pop,
output logic [BRAM_ADDR_WIDTH:0] size,
input wire clear,
// probes
input wire larry,
input wire curly,
input wire moe,
input wire [3:0] shemp,
// input port
input wire [15:0] addr_i,
input wire [15:0] wdata_i,
input wire [15:0] rdata_i,
input wire rw_i,
input wire valid_i,
// output port
output reg [15:0] addr_o,
output reg [15:0] wdata_o,
output reg [15:0] rdata_o,
output reg rw_o,
output reg valid_o);
parameter BASE_ADDR = 0;
parameter SAMPLE_DEPTH = 0;
localparam BRAM_ADDR_WIDTH = $clog2(SAMPLE_DEPTH);
// bus controller
reg [BRAM_ADDR_WIDTH-1:0] bram_read_addr;
reg [15:0] bram_read_data;
always @(*) begin
// if address is valid
if ( (addr_i >= BASE_ADDR) && (addr_i <= BASE_ADDR + SAMPLE_DEPTH) ) begin
// figure out proper place to read from
// want to read from the read pointer, and then loop back around
if(read_pointer + (addr_i - BASE_ADDR) > SAMPLE_DEPTH)
bram_read_addr = read_pointer + (addr_i - BASE_ADDR) - SAMPLE_DEPTH;
else
bram_read_addr = read_pointer + (addr_i - BASE_ADDR);
end
else bram_read_addr = 0;
end
// pipeline bus to compensate for 2-cycles of delay in BRAM
reg [15:0] addr_pip;
reg [15:0] wdata_pip;
reg [15:0] rdata_pip;
reg rw_pip;
reg valid_pip;
always @(posedge clk) begin
addr_pip <= addr_i;
wdata_pip <= wdata_i;
rdata_pip <= rdata_i;
rw_pip <= rw_i;
valid_pip <= valid_i;
addr_o <= addr_pip;
wdata_o <= wdata_pip;
rdata_o <= rdata_pip;
rw_o <= rw_pip;
valid_o <= valid_pip;
if( valid_pip && !rw_pip && (addr_pip >= BASE_ADDR) && (addr_pip <= BASE_ADDR + SAMPLE_DEPTH) )
rdata_o <= bram_read_data;
end
// bram
dual_port_bram #(
.RAM_WIDTH(16),
.RAM_DEPTH(SAMPLE_DEPTH)
) bram (
// read port (controlled by bus)
.clka(clk),
.addra(bram_read_addr),
.dina(16'b0),
.wea(1'b0),
.douta(bram_read_data),
// write port (controlled by FIFO)
.clkb(clk),
.addrb(write_pointer[BRAM_ADDR_WIDTH-1:0]),
.dinb({9'b0, larry, curly, moe, shemp}),
.web(acquire),
.doutb());
// fifo
reg [BRAM_ADDR_WIDTH:0] write_pointer = 0;
reg [BRAM_ADDR_WIDTH:0] read_pointer = 0;
assign size = write_pointer - read_pointer;
always @(posedge clk) begin
if (clear) read_pointer <= write_pointer;
if (acquire && size < SAMPLE_DEPTH) write_pointer <= write_pointer + 1'd1;
if (pop && size > 0) read_pointer <= read_pointer + 1'd1;
end
endmodule
`default_nettype wire