42 lines
2.1 KiB
Verilog
42 lines
2.1 KiB
Verilog
/*
|
||
* Двухтактовая память захвата FPGA: запись и чтение обслуживаются независимыми тактовыми
|
||
* входами. Чтение регистровое, выход обновляется по rd_clk; одновременный доступ к одному
|
||
* адресу требует учёта поведения выбранной FPGA-памяти.
|
||
*/
|
||
|
||
// Portable dual-clock capture RAM for FPGA logic analyzers.
|
||
// The module intentionally contains no vendor primitives: Quartus infers M9K
|
||
// blocks on Cyclone IV, while other tools may infer their native block RAM.
|
||
module la_capture_buffer #(
|
||
parameter SAMPLE_WIDTH = 16,
|
||
parameter ADDR_WIDTH = 12
|
||
) (
|
||
input wire wr_clk,
|
||
input wire wr_en,
|
||
input wire [ADDR_WIDTH-1:0] wr_addr,
|
||
input wire [SAMPLE_WIDTH-1:0] wr_data,
|
||
|
||
input wire rd_clk,
|
||
input wire [ADDR_WIDTH-1:0] rd_addr,
|
||
output reg [SAMPLE_WIDTH-1:0] rd_data
|
||
);
|
||
// ADDR_WIDTH задаёт логарифм ёмкости: каждый дополнительный адресный бит
|
||
// удваивает число хранимых отсчётов, не меняя разрядность одного отсчёта.
|
||
localparam DEPTH = (1 << ADDR_WIDTH);
|
||
|
||
reg [SAMPLE_WIDTH-1:0] memory [0:DEPTH-1];
|
||
|
||
// Разрешение записи действует только на фронте wr_clk. Память не имеет
|
||
// сброса: до первой записи содержимое адреса не считается определённым.
|
||
always @(posedge wr_clk) begin
|
||
if (wr_en)
|
||
memory[wr_addr] <= wr_data;
|
||
end
|
||
|
||
// Registered read is supported directly by Cyclone IV M9K blocks.
|
||
// Нет rd_en: на каждом фронте читается текущий адрес. Согласование
|
||
// владения областями между доменами частот выполняет внешняя логика.
|
||
always @(posedge rd_clk)
|
||
rd_data <= memory[rd_addr];
|
||
endmodule
|