rename lut mem to lut ram, add to manta generator
This commit is contained in:
parent
8630da53d8
commit
aa2ba43e8f
6
Makefile
6
Makefile
|
|
@ -8,7 +8,7 @@ lint:
|
||||||
python3 -m black src/manta/__init__.py
|
python3 -m black src/manta/__init__.py
|
||||||
python3 -m black src/manta/__main__.py
|
python3 -m black src/manta/__main__.py
|
||||||
|
|
||||||
sim: sim_bit_fifo sim_bridge_rx sim_bridge_tx fifo_tb lut_mem_tb uart_tx_tb
|
sim: sim_bit_fifo sim_bridge_rx sim_bridge_tx fifo_tb lut_ram_tb uart_tx_tb
|
||||||
|
|
||||||
sim_bit_fifo:
|
sim_bit_fifo:
|
||||||
iverilog -g2012 -o sim.out test/bit_fifo_tb.sv src/manta/bit_fifo.v
|
iverilog -g2012 -o sim.out test/bit_fifo_tb.sv src/manta/bit_fifo.v
|
||||||
|
|
@ -30,8 +30,8 @@ fifo_tb:
|
||||||
vvp sim.out >> /dev/null # this one is noisy right now
|
vvp sim.out >> /dev/null # this one is noisy right now
|
||||||
rm sim.out
|
rm sim.out
|
||||||
|
|
||||||
lut_mem_tb:
|
lut_ram_tb:
|
||||||
iverilog -g2012 -o sim.out test/lut_mem_tb.sv src/manta/lut_mem.v
|
iverilog -g2012 -o sim.out test/lut_ram_tb.sv src/manta/lut_ram.v
|
||||||
vvp sim.out
|
vvp sim.out
|
||||||
rm sim.out
|
rm sim.out
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,498 @@
|
||||||
|
`default_nettype none
|
||||||
|
`timescale 1ns/1ps
|
||||||
|
|
||||||
|
/*
|
||||||
|
This manta definition was generated on 14 Mar 2023 at 13:06:49 by fischerm
|
||||||
|
|
||||||
|
If this breaks or if you've got dank formal verification memes,
|
||||||
|
please contact fischerm [at] mit.edu
|
||||||
|
|
||||||
|
Provided under a GNU GPLv3 license. Go wild.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module manta (
|
||||||
|
input wire clk,
|
||||||
|
|
||||||
|
input wire rx,
|
||||||
|
output reg tx,
|
||||||
|
|
||||||
|
input wire larry,
|
||||||
|
input wire curly,
|
||||||
|
input wire moe,
|
||||||
|
input wire [3:0] shemp);
|
||||||
|
|
||||||
|
rx_uart #(.CLOCKS_PER_BAUD(868)) urx (
|
||||||
|
.i_clk(clk),
|
||||||
|
.i_uart_rx(rx),
|
||||||
|
.o_wr(urx_brx_axiv),
|
||||||
|
.o_data(urx_brx_axid));
|
||||||
|
|
||||||
|
logic [7:0] urx_brx_axid;
|
||||||
|
logic urx_brx_axiv;
|
||||||
|
|
||||||
|
bridge_rx brx (
|
||||||
|
.clk(clk),
|
||||||
|
|
||||||
|
.rx_data(urx_brx_axid),
|
||||||
|
.rx_valid(urx_brx_axiv),
|
||||||
|
|
||||||
|
.addr_o(brx_my_logic_analyzer_addr),
|
||||||
|
.wdata_o(brx_my_logic_analyzer_wdata),
|
||||||
|
.rw_o(brx_my_logic_analyzer_rw),
|
||||||
|
.valid_o(brx_my_logic_analyzer_valid));
|
||||||
|
|
||||||
|
reg [15:0] brx_my_logic_analyzer_addr;
|
||||||
|
reg [15:0] brx_my_logic_analyzer_wdata;
|
||||||
|
reg brx_my_logic_analyzer_rw;
|
||||||
|
reg brx_my_logic_analyzer_valid;
|
||||||
|
|
||||||
|
la_core my_logic_analyzer (
|
||||||
|
.clk(clk),
|
||||||
|
|
||||||
|
.addr_i(brx_my_logic_analyzer_addr),
|
||||||
|
.wdata_i(brx_my_logic_analyzer_wdata),
|
||||||
|
.rdata_i(),
|
||||||
|
.rw_i(brx_my_logic_analyzer_rw),
|
||||||
|
.valid_i(brx_my_logic_analyzer_valid),
|
||||||
|
|
||||||
|
.larry(larry),
|
||||||
|
.curly(curly),
|
||||||
|
.moe(moe),
|
||||||
|
.shemp(shemp),
|
||||||
|
|
||||||
|
.addr_o(),
|
||||||
|
.wdata_o(),
|
||||||
|
.rdata_o(my_logic_analyzer_btx_rdata),
|
||||||
|
.rw_o(my_logic_analyzer_btx_rw),
|
||||||
|
.valid_o(my_logic_analyzer_btx_valid));
|
||||||
|
|
||||||
|
reg [15:0] my_logic_analyzer_btx_rdata;
|
||||||
|
reg my_logic_analyzer_btx_rw;
|
||||||
|
reg my_logic_analyzer_btx_valid;
|
||||||
|
|
||||||
|
bridge_tx btx (
|
||||||
|
.clk(clk),
|
||||||
|
|
||||||
|
.rdata_i(my_logic_analyzer_btx_rdata),
|
||||||
|
.rw_i(my_logic_analyzer_btx_rw),
|
||||||
|
.valid_i(my_logic_analyzer_btx_valid),
|
||||||
|
|
||||||
|
.ready_i(utx_btx_ready),
|
||||||
|
.data_o(btx_utx_data),
|
||||||
|
.valid_o(btx_utx_valid));
|
||||||
|
|
||||||
|
logic utx_btx_ready;
|
||||||
|
logic btx_utx_valid;
|
||||||
|
logic [7:0] btx_utx_data;
|
||||||
|
|
||||||
|
uart_tx #(.CLOCKS_PER_BAUD(868)) utx (
|
||||||
|
.clk(clk),
|
||||||
|
|
||||||
|
.data(btx_utx_data),
|
||||||
|
.valid(btx_utx_valid),
|
||||||
|
.ready(utx_btx_ready),
|
||||||
|
|
||||||
|
.tx(tx));
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
/* ---- Module Definitions ---- */
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Filename: rxuart.v
|
||||||
|
//
|
||||||
|
// Project: Verilog Tutorial Example file
|
||||||
|
//
|
||||||
|
// Purpose: Receives a character from a UART (serial port) wire. Key
|
||||||
|
// features of this core include:
|
||||||
|
//
|
||||||
|
// - The baud rate is constant, and set by the CLOCKS_PER_BAUD parameter.
|
||||||
|
// To be successful, one baud interval must be (approximately)
|
||||||
|
// equal to CLOCKS_PER_BAUD / CLOCK_RATE_HZ seconds long.
|
||||||
|
//
|
||||||
|
// - The protocol used is the basic 8N1: 8 data bits, 1 stop bit, and no
|
||||||
|
// parity.
|
||||||
|
//
|
||||||
|
// - This core has no reset
|
||||||
|
// - This core has no error detection for frame errors
|
||||||
|
// - This core cannot detect, report, or even recover from, a break
|
||||||
|
// condition on the line. A break condition is defined as a
|
||||||
|
// period of time where the i_uart_rx line is held low for longer
|
||||||
|
// than one data byte (10 baud intervals)
|
||||||
|
//
|
||||||
|
// - There's no clock rate detection in this core
|
||||||
|
//
|
||||||
|
// Perhaps one of the nicer features of this core is that it (can be)
|
||||||
|
// formally verified. It depends upon a separate (formally verified)
|
||||||
|
// transmit core for this purpose.
|
||||||
|
//
|
||||||
|
// As with the other cores within this tutorial, there may (or may not) be
|
||||||
|
// bugs within this design for you to find.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Creator: Dan Gisselquist, Ph.D.
|
||||||
|
// Gisselquist Technology, LLC
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// Written and distributed by Gisselquist Technology, LLC
|
||||||
|
//
|
||||||
|
// This program is hereby granted to the public domain.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
module rx_uart(
|
||||||
|
input wire i_clk,
|
||||||
|
input wire i_uart_rx,
|
||||||
|
output reg o_wr,
|
||||||
|
output reg [7:0] o_data);
|
||||||
|
|
||||||
|
parameter [15:0] CLOCKS_PER_BAUD = 868;
|
||||||
|
localparam [3:0] IDLE = 4'h0;
|
||||||
|
localparam [3:0] BIT_ZERO = 4'h1;
|
||||||
|
// localparam [3:0] BIT_ONE = 4'h2;
|
||||||
|
// localparam [3:0] BIT_TWO = 4'h3;
|
||||||
|
// localparam [3:0] BIT_THREE = 4'h4;
|
||||||
|
// localparam [3:0] BIT_FOUR = 4'h5;
|
||||||
|
// localparam [3:0] BIT_FIVE = 4'h6;
|
||||||
|
// localparam [3:0] BIT_SIX = 4'h7;
|
||||||
|
// localparam [3:0] BIT_SEVEN = 4'h8;
|
||||||
|
localparam [3:0] STOP_BIT = 4'h9;
|
||||||
|
|
||||||
|
reg [3:0] state;
|
||||||
|
reg [15:0] baud_counter;
|
||||||
|
reg zero_baud_counter;
|
||||||
|
|
||||||
|
// 2FF Synchronizer
|
||||||
|
//
|
||||||
|
reg ck_uart;
|
||||||
|
reg q_uart;
|
||||||
|
initial { ck_uart, q_uart } = -1;
|
||||||
|
always @(posedge i_clk)
|
||||||
|
{ ck_uart, q_uart } <= { q_uart, i_uart_rx };
|
||||||
|
|
||||||
|
initial state = IDLE;
|
||||||
|
initial baud_counter = 0;
|
||||||
|
|
||||||
|
always @(posedge i_clk)
|
||||||
|
if (state == IDLE) begin
|
||||||
|
state <= IDLE;
|
||||||
|
baud_counter <= 0;
|
||||||
|
if (!ck_uart) begin
|
||||||
|
state <= BIT_ZERO;
|
||||||
|
baud_counter <= CLOCKS_PER_BAUD+CLOCKS_PER_BAUD/2-1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
else if (zero_baud_counter) begin
|
||||||
|
state <= state + 1;
|
||||||
|
baud_counter <= CLOCKS_PER_BAUD-1'b1;
|
||||||
|
if (state == STOP_BIT) begin
|
||||||
|
state <= IDLE;
|
||||||
|
baud_counter <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
else baud_counter <= baud_counter - 1'b1;
|
||||||
|
|
||||||
|
always @(*)
|
||||||
|
zero_baud_counter = (baud_counter == 0);
|
||||||
|
|
||||||
|
always @(posedge i_clk)
|
||||||
|
if ((zero_baud_counter)&&(state != STOP_BIT))
|
||||||
|
o_data <= { ck_uart, o_data[7:1] };
|
||||||
|
|
||||||
|
initial o_wr = 1'b0;
|
||||||
|
always @(posedge i_clk)
|
||||||
|
o_wr <= ((zero_baud_counter)&&(state == STOP_BIT));
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module bridge_rx(
|
||||||
|
input wire clk,
|
||||||
|
|
||||||
|
input wire[7:0] rx_data,
|
||||||
|
input wire rx_valid,
|
||||||
|
|
||||||
|
output reg[15:0] addr_o,
|
||||||
|
output reg[15:0] wdata_o,
|
||||||
|
output reg rw_o,
|
||||||
|
output reg valid_o
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// this is a hack, the FSM needs to be updated
|
||||||
|
// but this will bypass it for now
|
||||||
|
parameter ready_i = 1;
|
||||||
|
|
||||||
|
parameter ADDR_WIDTH = 0;
|
||||||
|
parameter DATA_WIDTH = 0;
|
||||||
|
|
||||||
|
localparam PREAMBLE = 8'h4D;
|
||||||
|
localparam CR = 8'h0D;
|
||||||
|
localparam LF = 8'h0A;
|
||||||
|
|
||||||
|
localparam ACQUIRE = 0;
|
||||||
|
localparam TRANSMIT = 1;
|
||||||
|
localparam ERROR = 2;
|
||||||
|
|
||||||
|
reg [1:0] state;
|
||||||
|
reg [3:0] bytes_received;
|
||||||
|
|
||||||
|
// no global resets!
|
||||||
|
initial begin
|
||||||
|
addr_o = 0;
|
||||||
|
wdata_o = 0;
|
||||||
|
rw_o = 0;
|
||||||
|
valid_o = 0;
|
||||||
|
bytes_received = 0;
|
||||||
|
state = ACQUIRE;
|
||||||
|
end
|
||||||
|
|
||||||
|
reg [3:0] rx_data_decoded;
|
||||||
|
reg rx_data_is_0_thru_9;
|
||||||
|
reg rx_data_is_A_thru_F;
|
||||||
|
|
||||||
|
always @(*) begin
|
||||||
|
rx_data_is_0_thru_9 = (rx_data >= 8'h30) & (rx_data <= 8'h39);
|
||||||
|
rx_data_is_A_thru_F = (rx_data >= 8'h41) & (rx_data <= 8'h46);
|
||||||
|
|
||||||
|
if (rx_data_is_0_thru_9) rx_data_decoded = rx_data - 8'h30;
|
||||||
|
else if (rx_data_is_A_thru_F) rx_data_decoded = rx_data - 8'h41 + 'd10;
|
||||||
|
else rx_data_decoded = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (state == ACQUIRE) begin
|
||||||
|
if(rx_valid) begin
|
||||||
|
|
||||||
|
if (bytes_received == 0) begin
|
||||||
|
if(rx_data == PREAMBLE) bytes_received <= 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
else if( (bytes_received >= 1) & (bytes_received <= 4) ) begin
|
||||||
|
// only advance if byte is valid hex digit
|
||||||
|
if(rx_data_is_0_thru_9 | rx_data_is_A_thru_F) begin
|
||||||
|
addr_o <= (addr_o << 4) | rx_data_decoded;
|
||||||
|
bytes_received <= bytes_received + 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
else state <= ERROR;
|
||||||
|
end
|
||||||
|
|
||||||
|
else if( bytes_received == 5) begin
|
||||||
|
if( (rx_data == CR) | (rx_data == LF)) begin
|
||||||
|
valid_o <= 1;
|
||||||
|
rw_o = 0;
|
||||||
|
bytes_received <= 0;
|
||||||
|
state <= TRANSMIT;
|
||||||
|
end
|
||||||
|
|
||||||
|
else if (rx_data_is_0_thru_9 | rx_data_is_A_thru_F) begin
|
||||||
|
bytes_received <= bytes_received + 1;
|
||||||
|
wdata_o <= (wdata_o << 4) | rx_data_decoded;
|
||||||
|
end
|
||||||
|
|
||||||
|
else state <= ERROR;
|
||||||
|
end
|
||||||
|
|
||||||
|
else if ( (bytes_received >= 6) & (bytes_received <= 8) ) begin
|
||||||
|
|
||||||
|
if (rx_data_is_0_thru_9 | rx_data_is_A_thru_F) begin
|
||||||
|
wdata_o <= (wdata_o << 4) | rx_data_decoded;
|
||||||
|
bytes_received <= bytes_received + 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
else state <= ERROR;
|
||||||
|
end
|
||||||
|
|
||||||
|
else if (bytes_received == 9) begin
|
||||||
|
bytes_received <= 0;
|
||||||
|
if( (rx_data == CR) | (rx_data == LF)) begin
|
||||||
|
valid_o <= 1;
|
||||||
|
rw_o <= 1;
|
||||||
|
state <= TRANSMIT;
|
||||||
|
end
|
||||||
|
|
||||||
|
else state <= ERROR;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
else if (state == TRANSMIT) begin
|
||||||
|
if(ready_i) begin
|
||||||
|
valid_o <= 0;
|
||||||
|
state <= ACQUIRE;
|
||||||
|
end
|
||||||
|
|
||||||
|
if(rx_valid) begin
|
||||||
|
if ( (rx_data != CR) & (rx_data != LF)) begin
|
||||||
|
valid_o <= 0;
|
||||||
|
state <= ERROR;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module bridge_tx(
|
||||||
|
input wire clk,
|
||||||
|
|
||||||
|
input wire [15:0] rdata_i,
|
||||||
|
input wire rw_i,
|
||||||
|
input wire valid_i,
|
||||||
|
|
||||||
|
output reg [7:0] data_o,
|
||||||
|
input wire ready_i,
|
||||||
|
output reg valid_o);
|
||||||
|
|
||||||
|
localparam PREAMBLE = 8'h4D;
|
||||||
|
localparam CR = 8'h0D;
|
||||||
|
localparam LF = 8'h0A;
|
||||||
|
|
||||||
|
logic busy;
|
||||||
|
logic [15:0] buffer;
|
||||||
|
logic [3:0] byte_counter;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
busy = 0;
|
||||||
|
buffer = 0;
|
||||||
|
byte_counter = 0;
|
||||||
|
valid_o = 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (!busy) begin
|
||||||
|
if (valid_i && !rw_i) begin
|
||||||
|
busy <= 1;
|
||||||
|
buffer <= rdata_i;
|
||||||
|
byte_counter <= 0;
|
||||||
|
valid_o <= 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if (busy) begin
|
||||||
|
|
||||||
|
if(ready_i) begin
|
||||||
|
byte_counter <= byte_counter + 1;
|
||||||
|
|
||||||
|
if (byte_counter > 5) begin
|
||||||
|
byte_counter <= 0;
|
||||||
|
|
||||||
|
// stop transmitting if we don't have both valid and read
|
||||||
|
if ( !(valid_i && !rw_i) ) begin
|
||||||
|
busy <= 0;
|
||||||
|
valid_o <= 0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(*) begin
|
||||||
|
case (byte_counter)
|
||||||
|
0: data_o = PREAMBLE;
|
||||||
|
1: data_o = (buffer[15:12] < 10) ? (buffer[15:12] + 8'h30) : (buffer[15:12] + 8'h41 - 'd10);
|
||||||
|
2: data_o = (buffer[11:8] < 10) ? (buffer[11:8] + 8'h30) : (buffer[11:8] + 8'h41 - 'd10);
|
||||||
|
3: data_o = (buffer[7:4] < 10) ? (buffer[7:4] + 8'h30) : (buffer[7:4] + 8'h41 - 'd10);
|
||||||
|
4: data_o = (buffer[3:0] < 10) ? (buffer[3:0] + 8'h30) : (buffer[3:0] + 8'h41 - 'd10);
|
||||||
|
5: data_o = CR;
|
||||||
|
6: data_o = LF;
|
||||||
|
default: data_o = 0;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module uart_tx(
|
||||||
|
input wire clk,
|
||||||
|
|
||||||
|
input wire [7:0] data,
|
||||||
|
input wire valid,
|
||||||
|
output reg busy,
|
||||||
|
output reg ready,
|
||||||
|
|
||||||
|
output reg tx);
|
||||||
|
|
||||||
|
// this transmitter only works with 8N1 serial, at configurable baudrate
|
||||||
|
parameter CLOCKS_PER_BAUD = 868;
|
||||||
|
|
||||||
|
reg [9:0] baud_counter;
|
||||||
|
reg [8:0] data_buf;
|
||||||
|
reg [3:0] bit_index;
|
||||||
|
|
||||||
|
initial begin
|
||||||
|
baud_counter = CLOCKS_PER_BAUD;
|
||||||
|
data_buf = 0;
|
||||||
|
bit_index = 0;
|
||||||
|
busy = 0;
|
||||||
|
ready = 1;
|
||||||
|
tx = 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (valid && !busy) begin
|
||||||
|
data_buf <= {1'b1, data};
|
||||||
|
bit_index <= 0;
|
||||||
|
tx <= 0; //wafflestomp that start bit
|
||||||
|
baud_counter <= CLOCKS_PER_BAUD - 1;
|
||||||
|
busy <= 1;
|
||||||
|
ready <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
else if (busy) begin
|
||||||
|
baud_counter <= baud_counter - 1;
|
||||||
|
|
||||||
|
ready <= (baud_counter == 1) && (bit_index == 9);
|
||||||
|
|
||||||
|
if (baud_counter == 0) begin
|
||||||
|
baud_counter <= CLOCKS_PER_BAUD - 1;
|
||||||
|
|
||||||
|
|
||||||
|
if (bit_index == 9) begin
|
||||||
|
if(valid) begin
|
||||||
|
data_buf <= {1'b1, data};
|
||||||
|
bit_index <= 0;
|
||||||
|
tx <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
else begin
|
||||||
|
busy <= 0;
|
||||||
|
ready <= 1;
|
||||||
|
end
|
||||||
|
// if valid happens here then we should bool
|
||||||
|
end
|
||||||
|
|
||||||
|
else begin
|
||||||
|
tx <= data_buf[bit_index];
|
||||||
|
bit_index <= bit_index + 1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
`default_nettype wire
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
---
|
||||||
|
cores:
|
||||||
|
my_lut_ram:
|
||||||
|
type: lut_ram
|
||||||
|
size: 64
|
||||||
|
|
||||||
|
uart:
|
||||||
|
port: "/dev/tty.usbserial-2102926963071"
|
||||||
|
baudrate: 115200
|
||||||
|
clock_freq: 100000000
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
`timescale 1ns/1ps
|
`timescale 1ns/1ps
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This manta definition was generated on 09 Mar 2023 at 23:58:38 by fischerm
|
This manta definition was generated on 14 Mar 2023 at 13:06:49 by fischerm
|
||||||
|
|
||||||
If this breaks or if you've got dank formal verification memes,
|
If this breaks or if you've got dank formal verification memes,
|
||||||
please contact fischerm [at] mit.edu
|
please contact fischerm [at] mit.edu
|
||||||
|
|
@ -31,41 +31,41 @@ module manta (
|
||||||
.rx_data(urx_brx_axid),
|
.rx_data(urx_brx_axid),
|
||||||
.rx_valid(urx_brx_axiv),
|
.rx_valid(urx_brx_axiv),
|
||||||
|
|
||||||
.addr_o(brx_my_logic_analyzer_addr),
|
.addr_o(brx_my_lut_ram_addr),
|
||||||
.wdata_o(brx_my_logic_analyzer_wdata),
|
.wdata_o(brx_my_lut_ram_wdata),
|
||||||
.rw_o(brx_my_logic_analyzer_rw),
|
.rw_o(brx_my_lut_ram_rw),
|
||||||
.valid_o(brx_my_logic_analyzer_valid));
|
.valid_o(brx_my_lut_ram_valid));
|
||||||
|
|
||||||
reg [15:0] brx_my_logic_analyzer_addr;
|
reg [15:0] brx_my_lut_ram_addr;
|
||||||
reg [15:0] brx_my_logic_analyzer_wdata;
|
reg [15:0] brx_my_lut_ram_wdata;
|
||||||
reg brx_my_logic_analyzer_rw;
|
reg brx_my_lut_ram_rw;
|
||||||
reg brx_my_logic_analyzer_valid;
|
reg brx_my_lut_ram_valid;
|
||||||
|
|
||||||
lut_mem my_logic_analyzer(
|
lut_ram #(.DEPTH(64)) my_lut_ram (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
|
|
||||||
.addr_i(brx_my_logic_analyzer_addr),
|
.addr_i(brx_my_lut_ram_addr),
|
||||||
.wdata_i(brx_my_logic_analyzer_wdata),
|
.wdata_i(brx_my_lut_ram_wdata),
|
||||||
.rdata_i(),
|
.rdata_i(),
|
||||||
.rw_i(brx_my_logic_analyzer_rw),
|
.rw_i(brx_my_lut_ram_rw),
|
||||||
.valid_i(brx_my_logic_analyzer_valid),
|
.valid_i(brx_my_lut_ram_valid),
|
||||||
|
|
||||||
.addr_o(),
|
.addr_o(),
|
||||||
.wdata_o(),
|
.wdata_o(),
|
||||||
.rdata_o(my_logic_analyzer_btx_rdata),
|
.rdata_o(my_lut_ram_btx_rdata),
|
||||||
.rw_o(my_logic_analyzer_btx_rw),
|
.rw_o(my_lut_ram_btx_rw),
|
||||||
.valid_o(my_logic_analyzer_btx_valid));
|
.valid_o(my_lut_ram_btx_valid));
|
||||||
|
|
||||||
reg [15:0] my_logic_analyzer_btx_rdata;
|
reg [15:0] my_lut_ram_btx_rdata;
|
||||||
reg my_logic_analyzer_btx_rw;
|
reg my_lut_ram_btx_rw;
|
||||||
reg my_logic_analyzer_btx_valid;
|
reg my_lut_ram_btx_valid;
|
||||||
|
|
||||||
bridge_tx btx (
|
bridge_tx btx (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
|
|
||||||
.rdata_i(my_logic_analyzer_btx_rdata),
|
.rdata_i(my_lut_ram_btx_rdata),
|
||||||
.rw_i(my_logic_analyzer_btx_rw),
|
.rw_i(my_lut_ram_btx_rw),
|
||||||
.valid_i(my_logic_analyzer_btx_valid),
|
.valid_i(my_lut_ram_btx_valid),
|
||||||
|
|
||||||
.ready_i(utx_btx_ready),
|
.ready_i(utx_btx_ready),
|
||||||
.data_o(btx_utx_data),
|
.data_o(btx_utx_data),
|
||||||
|
|
@ -340,6 +340,53 @@ endmodule
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
module lut_ram(
|
||||||
|
input wire clk,
|
||||||
|
|
||||||
|
// 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 DEPTH = 8;
|
||||||
|
parameter BASE_ADDR = 0;
|
||||||
|
parameter READ_ONLY = 0;
|
||||||
|
reg [DEPTH-1:0][15:0] mem;
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
addr_o <= addr_i;
|
||||||
|
wdata_o <= wdata_i;
|
||||||
|
rdata_o <= rdata_i;
|
||||||
|
rw_o <= rw_i;
|
||||||
|
valid_o <= valid_i;
|
||||||
|
rdata_o <= rdata_i;
|
||||||
|
|
||||||
|
|
||||||
|
if(valid_i) begin
|
||||||
|
// check if address is valid
|
||||||
|
if( (addr_i >= BASE_ADDR) && (addr_i <= BASE_ADDR + DEPTH - 1) ) begin
|
||||||
|
|
||||||
|
// read/write
|
||||||
|
if (rw_i && !READ_ONLY) mem[addr_i - BASE_ADDR] <= wdata_i;
|
||||||
|
else rdata_o <= mem[addr_i - BASE_ADDR];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
module bridge_tx(
|
module bridge_tx(
|
||||||
input wire clk,
|
input wire clk,
|
||||||
|
|
@ -485,53 +532,4 @@ module uart_tx(
|
||||||
endmodule
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
`default_nettype none
|
|
||||||
`timescale 1ns/1ps
|
|
||||||
|
|
||||||
module lut_mem(
|
|
||||||
input wire clk,
|
|
||||||
|
|
||||||
// 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 DEPTH = 8;
|
|
||||||
parameter BASE_ADDR = 0;
|
|
||||||
parameter READ_ONLY = 0;
|
|
||||||
reg [DEPTH-1:0][15:0] mem;
|
|
||||||
|
|
||||||
always @(posedge clk) begin
|
|
||||||
addr_o <= addr_i;
|
|
||||||
wdata_o <= wdata_i;
|
|
||||||
rdata_o <= rdata_i;
|
|
||||||
rw_o <= rw_i;
|
|
||||||
valid_o <= valid_i;
|
|
||||||
rdata_o <= rdata_i;
|
|
||||||
|
|
||||||
|
|
||||||
if(valid_i) begin
|
|
||||||
// check if address is valid
|
|
||||||
if( (addr_i >= BASE_ADDR) && (addr_i <= BASE_ADDR + DEPTH - 1) ) begin
|
|
||||||
|
|
||||||
// read/write
|
|
||||||
if (rw_i && !READ_ONLY) mem[addr_i - BASE_ADDR] <= wdata_i;
|
|
||||||
else rdata_o <= mem[addr_i - BASE_ADDR];
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
`default_nettype wire
|
|
||||||
|
|
||||||
`default_nettype wire
|
`default_nettype wire
|
||||||
|
|
@ -13,25 +13,20 @@ module top_level (
|
||||||
output logic uart_rxd_out
|
output logic uart_rxd_out
|
||||||
);
|
);
|
||||||
|
|
||||||
// Signal Generator
|
|
||||||
// logic [7:0] count;
|
|
||||||
// always_ff @(posedge clk) count <= count + 1;
|
|
||||||
|
|
||||||
|
|
||||||
manta manta (
|
manta manta (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
|
|
||||||
.rx(uart_txd_in),
|
.rx(uart_txd_in),
|
||||||
.tx(uart_rxd_out));
|
.tx(uart_rxd_out));
|
||||||
|
|
||||||
assign led = manta.brx_my_logic_analyzer_addr;
|
assign led = manta.brx_my_lut_ram_addr;
|
||||||
|
|
||||||
logic [6:0] cat;
|
logic [6:0] cat;
|
||||||
assign {cg,cf,ce,cd,cc,cb,ca} = cat;
|
assign {cg,cf,ce,cd,cc,cb,ca} = cat;
|
||||||
ssd ssd (
|
ssd ssd (
|
||||||
.clk_in(clk),
|
.clk_in(clk),
|
||||||
.rst_in(btnc),
|
.rst_in(btnc),
|
||||||
.val_in( (manta.my_logic_analyzer_btx_rdata << 16) | (manta.brx_my_logic_analyzer_wdata) ),
|
.val_in( (manta.my_lut_ram_btx_rdata << 16) | (manta.brx_my_lut_ram_wdata) ),
|
||||||
.cat_out(cat),
|
.cat_out(cat),
|
||||||
.an_out(an));
|
.an_out(an));
|
||||||
|
|
||||||
|
|
@ -48,8 +48,7 @@ class UARTInterface:
|
||||||
def hdl_top_level_ports(self):
|
def hdl_top_level_ports(self):
|
||||||
# this should return the probes that we want to connect to top-level, but like as a string of verilog
|
# this should return the probes that we want to connect to top-level, but like as a string of verilog
|
||||||
|
|
||||||
return """input wire rx,
|
return ["input wire rx", "output reg tx"]
|
||||||
output reg tx,"""
|
|
||||||
|
|
||||||
def rx_hdl_def(self):
|
def rx_hdl_def(self):
|
||||||
uart_rx_def = pkgutil.get_data(__name__, "rx_uart.v").decode()
|
uart_rx_def = pkgutil.get_data(__name__, "rx_uart.v").decode()
|
||||||
|
|
@ -111,10 +110,39 @@ class UARTInterface:
|
||||||
.tx(tx));\n"""
|
.tx(tx));\n"""
|
||||||
|
|
||||||
|
|
||||||
class IOCore:
|
class LUTRAMCore:
|
||||||
def __init__(self, config, interface):
|
def __init__(self, config, interface):
|
||||||
self.interface = interface
|
self.interface = interface
|
||||||
|
|
||||||
|
assert "size" in config, "Size not specified for LUT RAM core."
|
||||||
|
self.size = config["size"]
|
||||||
|
|
||||||
|
def hdl_inst(self):
|
||||||
|
hdl = f"""
|
||||||
|
lut_ram #(.DEPTH({self.size})) {self.name} (
|
||||||
|
.clk(clk),
|
||||||
|
|
||||||
|
.addr_i(),
|
||||||
|
.wdata_i(),
|
||||||
|
.rdata_i(),
|
||||||
|
.rw_i(),
|
||||||
|
.valid_i(),
|
||||||
|
|
||||||
|
.addr_o(),
|
||||||
|
.wdata_o(),
|
||||||
|
.rdata_o(),
|
||||||
|
.rw_o(),
|
||||||
|
.valid_o());\n"""
|
||||||
|
|
||||||
|
return hdl
|
||||||
|
|
||||||
|
def hdl_def(self):
|
||||||
|
hdl = pkgutil.get_data(__name__, "lut_ram.v").decode()
|
||||||
|
return hdl
|
||||||
|
|
||||||
|
def hdl_top_level_ports(self):
|
||||||
|
# no top_level connections since this core just lives on the bus
|
||||||
|
return []
|
||||||
|
|
||||||
class LogicAnalyzerCore:
|
class LogicAnalyzerCore:
|
||||||
def __init__(self, config, interface):
|
def __init__(self, config, interface):
|
||||||
|
|
@ -274,16 +302,16 @@ class LogicAnalyzerCore:
|
||||||
return tmpl
|
return tmpl
|
||||||
|
|
||||||
def hdl_top_level_ports(self):
|
def hdl_top_level_ports(self):
|
||||||
# this should return the probes that we want to connect to top-level, but like as a string of verilog
|
# this should return the probes that we want to connect to top-level, but as a list of verilog ports
|
||||||
|
|
||||||
ports = []
|
ports = []
|
||||||
for name, width in self.probes.items():
|
for name, width in self.probes.items():
|
||||||
if width == 1:
|
if width == 1:
|
||||||
ports.append(f"input wire {name},")
|
ports.append(f"input wire {name}")
|
||||||
else:
|
else:
|
||||||
ports.append(f"input wire [{width-1}:0] {name},")
|
ports.append(f"input wire [{width-1}:0] {name}")
|
||||||
|
|
||||||
return "\n ".join(ports)
|
return ports
|
||||||
|
|
||||||
class Manta:
|
class Manta:
|
||||||
def __init__(self, config_filepath):
|
def __init__(self, config_filepath):
|
||||||
|
|
@ -314,6 +342,9 @@ class Manta:
|
||||||
elif core["type"] == "io":
|
elif core["type"] == "io":
|
||||||
new_core = IOCore(core, self.interface)
|
new_core = IOCore(core, self.interface)
|
||||||
|
|
||||||
|
elif core["type"] == "lut_ram":
|
||||||
|
new_core = LUTRAMCore(core, self.interface)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Unrecognized core type specified for {core_name}.")
|
raise ValueError(f"Unrecognized core type specified for {core_name}.")
|
||||||
|
|
||||||
|
|
@ -380,23 +411,24 @@ class Manta:
|
||||||
|
|
||||||
else:
|
else:
|
||||||
src_name = self.cores[i-1].name
|
src_name = self.cores[i-1].name
|
||||||
|
hdl = hdl.replace(".rdata_i()", f".rdata_i({src_name}_{core.name}_rdata)")
|
||||||
|
|
||||||
hdl = hdl.replace(".addr_i()", f".addr_i({src_name}_{core.name}_addr)")
|
hdl = hdl.replace(".addr_i()", f".addr_i({src_name}_{core.name}_addr)")
|
||||||
hdl = hdl.replace(".wdata_i()", f".wdata_i({src_name}_{core.name}_wdata)")
|
hdl = hdl.replace(".wdata_i()", f".wdata_i({src_name}_{core.name}_wdata)")
|
||||||
hdl = hdl.replace(".rdata_i()", f".rdata_i({src_name}_{core.name}_rdata)")
|
|
||||||
hdl = hdl.replace(".rw_i()", f".rw_i({src_name}_{core.name}_rw)")
|
hdl = hdl.replace(".rw_i()", f".rw_i({src_name}_{core.name}_rw)")
|
||||||
hdl = hdl.replace(".valid_i()", f".valid_i({src_name}_{core.name}_valid)")
|
hdl = hdl.replace(".valid_i()", f".valid_i({src_name}_{core.name}_valid)")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# connect output
|
# connect output
|
||||||
if (i < len(self.cores)-1):
|
if (i < len(self.cores)-1):
|
||||||
dst_name = self.cores[i+1]
|
dst_name = self.cores[i+1]
|
||||||
|
hdl = hdl.replace(".addr_o()", f".addr_o({core.name}_{dst_name}_addr)")
|
||||||
|
hdl = hdl.replace(".wdata_o()", f".wdata_o({core.name}_{dst_name}_wdata)")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
dst_name = "btx"
|
dst_name = "btx"
|
||||||
|
|
||||||
hdl = hdl.replace(".addr_o()", f".addr_o({core.name}_{dst_name}_addr)")
|
|
||||||
hdl = hdl.replace(".wdata_o()", f".wdata_o({core.name}_{dst_name}_wdata)")
|
|
||||||
hdl = hdl.replace(".rdata_o()", f".rdata_o({core.name}_{dst_name}_rdata)")
|
hdl = hdl.replace(".rdata_o()", f".rdata_o({core.name}_{dst_name}_rdata)")
|
||||||
hdl = hdl.replace(".rw_o()", f".rw_o({core.name}_{dst_name}_rw)")
|
hdl = hdl.replace(".rw_o()", f".rw_o({core.name}_{dst_name}_rw)")
|
||||||
hdl = hdl.replace(".valid_o()", f".valid_o({core.name}_{dst_name}_valid)")
|
hdl = hdl.replace(".valid_o()", f".valid_o({core.name}_{dst_name}_valid)")
|
||||||
|
|
@ -438,17 +470,31 @@ Provided under a GNU GPLv3 license. Go wild.
|
||||||
# get all the top level connections for each module.
|
# get all the top level connections for each module.
|
||||||
|
|
||||||
interface_ports = self.interface.hdl_top_level_ports()
|
interface_ports = self.interface.hdl_top_level_ports()
|
||||||
|
interface_ports = [f" {port},\n" for port in interface_ports]
|
||||||
|
interface_ports = "".join(interface_ports) + "\n"
|
||||||
|
|
||||||
|
core_chain_ports = []
|
||||||
|
for core in self.cores:
|
||||||
|
ports = [f" {port},\n" for port in core.hdl_top_level_ports()]
|
||||||
|
ports = "".join(ports)
|
||||||
|
core_chain_ports.append(ports)
|
||||||
|
|
||||||
core_chain_ports = [core.hdl_top_level_ports() for core in self.cores]
|
|
||||||
core_chain_ports = "\n".join(core_chain_ports)
|
core_chain_ports = "\n".join(core_chain_ports)
|
||||||
|
|
||||||
|
ports = interface_ports + core_chain_ports
|
||||||
|
|
||||||
|
# remove trailing comma
|
||||||
|
ports = ports.rstrip()
|
||||||
|
if ports[-1] == ",":
|
||||||
|
ports = ports[:-1]
|
||||||
|
|
||||||
|
print(ports)
|
||||||
|
|
||||||
return f"""
|
return f"""
|
||||||
module manta (
|
module manta (
|
||||||
input wire clk,
|
input wire clk,
|
||||||
|
|
||||||
{interface_ports}
|
{ports});
|
||||||
|
|
||||||
{core_chain_ports});
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def generate_interface_rx(self):
|
def generate_interface_rx(self):
|
||||||
|
|
@ -480,10 +526,10 @@ module manta (
|
||||||
# instantiate interface_tx, substitute in register names
|
# instantiate interface_tx, substitute in register names
|
||||||
interface_tx_inst = self.interface.tx_hdl_inst()
|
interface_tx_inst = self.interface.tx_hdl_inst()
|
||||||
|
|
||||||
interface_tx_inst = interface_tx_inst.replace("addr_i()", f"addr_o({self.cores[0].name}_btx_addr)")
|
interface_tx_inst = interface_tx_inst.replace("addr_i()", f"addr_i({self.cores[0].name}_btx_addr)")
|
||||||
interface_tx_inst = interface_tx_inst.replace("rdata_i()", f"rdata_o({self.cores[0].name}_btx_rdata)")
|
interface_tx_inst = interface_tx_inst.replace("rdata_i()", f"rdata_i({self.cores[0].name}_btx_rdata)")
|
||||||
interface_tx_inst = interface_tx_inst.replace("rw_i()", f"rw_o({self.cores[0].name}_btx_rw)")
|
interface_tx_inst = interface_tx_inst.replace("rw_i()", f"rw_i({self.cores[0].name}_btx_rw)")
|
||||||
interface_tx_inst = interface_tx_inst.replace("valid_i()", f"valid_o({self.cores[0].name}_btx_valid)")
|
interface_tx_inst = interface_tx_inst.replace("valid_i()", f"valid_i({self.cores[0].name}_btx_valid)")
|
||||||
|
|
||||||
return interface_tx_conn + interface_tx_inst
|
return interface_tx_conn + interface_tx_inst
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
`default_nettype none
|
`default_nettype none
|
||||||
`timescale 1ns/1ps
|
`timescale 1ns/1ps
|
||||||
|
|
||||||
module lut_mem(
|
module lut_ram(
|
||||||
input wire clk,
|
input wire clk,
|
||||||
|
|
||||||
// input port
|
// input port
|
||||||
|
|
@ -56,10 +56,10 @@ module bus_fix_tb;
|
||||||
logic brx_mem_rw;
|
logic brx_mem_rw;
|
||||||
logic brx_mem_valid;
|
logic brx_mem_valid;
|
||||||
|
|
||||||
lut_mem #(
|
lut_ram #(
|
||||||
.DEPTH(32),
|
.DEPTH(32),
|
||||||
.BASE_ADDR(0)
|
.BASE_ADDR(0)
|
||||||
) mem (
|
) ram (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.addr_i(brx_mem_addr),
|
.addr_i(brx_mem_addr),
|
||||||
.wdata_i(brx_mem_wdata),
|
.wdata_i(brx_mem_wdata),
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
`define CP 10
|
`define CP 10
|
||||||
`define HCP 5
|
`define HCP 5
|
||||||
|
|
||||||
module lut_mem_tb;
|
module lut_ram_tb;
|
||||||
// https://www.youtube.com/watch?v=WCOAr-96bGc
|
// https://www.youtube.com/watch?v=WCOAr-96bGc
|
||||||
|
|
||||||
//boilerplate
|
//boilerplate
|
||||||
|
|
@ -17,7 +17,7 @@ module lut_mem_tb;
|
||||||
logic tb_mem_1_rw;
|
logic tb_mem_1_rw;
|
||||||
logic tb_mem_1_valid;
|
logic tb_mem_1_valid;
|
||||||
|
|
||||||
lut_mem #(
|
lut_ram #(
|
||||||
.DEPTH(8),
|
.DEPTH(8),
|
||||||
.BASE_ADDR(0)
|
.BASE_ADDR(0)
|
||||||
) mem_1 (
|
) mem_1 (
|
||||||
|
|
@ -42,7 +42,7 @@ module lut_mem_tb;
|
||||||
logic mem_1_mem_2_rw;
|
logic mem_1_mem_2_rw;
|
||||||
logic mem_1_mem_2_valid;
|
logic mem_1_mem_2_valid;
|
||||||
|
|
||||||
lut_mem #(
|
lut_ram #(
|
||||||
.DEPTH(8),
|
.DEPTH(8),
|
||||||
.BASE_ADDR(8)
|
.BASE_ADDR(8)
|
||||||
) mem_2 (
|
) mem_2 (
|
||||||
|
|
@ -67,7 +67,7 @@ module lut_mem_tb;
|
||||||
logic mem_2_mem_3_rw;
|
logic mem_2_mem_3_rw;
|
||||||
logic mem_2_mem_3_valid;
|
logic mem_2_mem_3_valid;
|
||||||
|
|
||||||
lut_mem #(
|
lut_ram #(
|
||||||
.DEPTH(8),
|
.DEPTH(8),
|
||||||
.BASE_ADDR(16)
|
.BASE_ADDR(16)
|
||||||
) mem_3 (
|
) mem_3 (
|
||||||
|
|
@ -98,8 +98,8 @@ module lut_mem_tb;
|
||||||
end
|
end
|
||||||
|
|
||||||
initial begin
|
initial begin
|
||||||
$dumpfile("lut_mem.vcd");
|
$dumpfile("lut_ram.vcd");
|
||||||
$dumpvars(0, lut_mem_tb);
|
$dumpvars(0, lut_ram_tb);
|
||||||
|
|
||||||
// setup and reset
|
// setup and reset
|
||||||
clk = 0;
|
clk = 0;
|
||||||
Loading…
Reference in New Issue