works (kinda) on hardware
This commit is contained in:
parent
70154f6904
commit
3ff4298e24
|
|
@ -0,0 +1,12 @@
|
|||
import serial
|
||||
from time import sleep
|
||||
|
||||
with serial.Serial("/dev/tty.usbserial-210292AE39A41", 115200) as ser:
|
||||
for i in range(8):
|
||||
req = '{:04X}'.format(i)
|
||||
req = f"M{req}\r\n "
|
||||
req = req.encode('ascii')
|
||||
|
||||
ser.write(req)
|
||||
resp = ser.read(7)
|
||||
print(f"req --> {req} resp (bytes) --> {resp}")
|
||||
|
|
@ -0,0 +1,129 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module bridge_rx(
|
||||
input wire clk,
|
||||
|
||||
input wire[7:0] axiid,
|
||||
input wire axiiv,
|
||||
|
||||
output reg[15:0] req_addr,
|
||||
output reg[15:0] req_data,
|
||||
output reg req_rw,
|
||||
output reg req_valid,
|
||||
input wire req_ready
|
||||
);
|
||||
|
||||
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
|
||||
req_addr = 0;
|
||||
req_data = 0;
|
||||
req_rw = 0;
|
||||
req_valid = 0;
|
||||
bytes_received = 0;
|
||||
state = ACQUIRE;
|
||||
end
|
||||
|
||||
reg [3:0] axiid_decoded;
|
||||
reg axiid_is_0_thru_9;
|
||||
reg axiid_is_A_thru_F;
|
||||
|
||||
always @(*) begin
|
||||
axiid_is_0_thru_9 = (axiid >= 8'h30) & (axiid <= 8'h39);
|
||||
axiid_is_A_thru_F = (axiid >= 8'h41) & (axiid <= 8'h46);
|
||||
|
||||
if (axiid_is_0_thru_9) axiid_decoded = axiid - 8'h30;
|
||||
else if (axiid_is_A_thru_F) axiid_decoded = axiid - 8'h41 + 'd10;
|
||||
else axiid_decoded = 0;
|
||||
end
|
||||
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (state == ACQUIRE) begin
|
||||
if(axiiv) begin
|
||||
|
||||
if (bytes_received == 0) begin
|
||||
if(axiid == PREAMBLE) bytes_received <= 1;
|
||||
end
|
||||
|
||||
else if( (bytes_received >= 1) & (bytes_received <= 4) ) begin
|
||||
// only advance if byte is valid hex digit
|
||||
if(axiid_is_0_thru_9 | axiid_is_A_thru_F) begin
|
||||
req_addr <= (req_addr << 4) | axiid_decoded;
|
||||
bytes_received <= bytes_received + 1;
|
||||
end
|
||||
|
||||
else state <= ERROR;
|
||||
end
|
||||
|
||||
else if( bytes_received == 5) begin
|
||||
if( (axiid == CR) | (axiid == LF)) begin
|
||||
req_valid <= 1;
|
||||
req_rw = 0;
|
||||
bytes_received <= 0;
|
||||
state <= TRANSMIT;
|
||||
end
|
||||
|
||||
else if (axiid_is_0_thru_9 | axiid_is_A_thru_F) begin
|
||||
bytes_received <= bytes_received + 1;
|
||||
req_data <= (req_data << 4) | axiid_decoded;
|
||||
end
|
||||
|
||||
else state <= ERROR;
|
||||
end
|
||||
|
||||
else if ( (bytes_received >= 6) & (bytes_received <= 8) ) begin
|
||||
|
||||
if (axiid_is_0_thru_9 | axiid_is_A_thru_F) begin
|
||||
req_data <= (req_data << 4) | axiid_decoded;
|
||||
bytes_received <= bytes_received + 1;
|
||||
end
|
||||
|
||||
else state <= ERROR;
|
||||
end
|
||||
|
||||
else if (bytes_received == 9) begin
|
||||
bytes_received <= 0;
|
||||
if( (axiid == CR) | (axiid == LF)) begin
|
||||
req_valid <= 1;
|
||||
req_rw <= 1;
|
||||
state <= TRANSMIT;
|
||||
end
|
||||
|
||||
else state <= ERROR;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
else if (state == TRANSMIT) begin
|
||||
if(req_ready) begin
|
||||
req_valid <= 0;
|
||||
state <= ACQUIRE;
|
||||
end
|
||||
|
||||
if(axiiv) begin
|
||||
if ( (axiid != CR) & (axiid != LF)) begin
|
||||
req_valid <= 0;
|
||||
state <= ERROR;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
`default_nettype wire
|
||||
|
|
@ -0,0 +1,93 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module bridge_tx(
|
||||
input wire clk,
|
||||
|
||||
output reg [7:0] axiod,
|
||||
output reg axiov,
|
||||
input wire axior,
|
||||
|
||||
input wire [15:0] res_data,
|
||||
input wire res_valid,
|
||||
output reg res_ready
|
||||
);
|
||||
|
||||
parameter ADDR_WIDTH = 0;
|
||||
parameter DATA_WDITH = 0;
|
||||
|
||||
localparam PREAMBLE = 8'h4D;
|
||||
localparam CR = 8'h0D;
|
||||
localparam LF = 8'h0A;
|
||||
|
||||
reg [3:0] bytes_transmitted;
|
||||
reg [15:0] buffer;
|
||||
|
||||
initial begin
|
||||
axiod = 0;
|
||||
axiov = 0;
|
||||
res_ready = 1;
|
||||
bytes_transmitted = 0;
|
||||
buffer = 0;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (res_ready) begin
|
||||
if(res_valid) begin
|
||||
buffer <= res_data;
|
||||
res_ready <= 0;
|
||||
bytes_transmitted <= 0;
|
||||
axiod <= PREAMBLE;
|
||||
axiov <= 1;
|
||||
end
|
||||
end
|
||||
|
||||
else begin
|
||||
if (bytes_transmitted == 0) begin
|
||||
if(axior) bytes_transmitted <= 1;
|
||||
end
|
||||
|
||||
if (bytes_transmitted == 1) begin
|
||||
axiod <= (buffer[15:12] < 10) ? (buffer[15:12] + 8'h30) : (buffer[15:12] + 8'h41 - 'd10);
|
||||
if (axior) bytes_transmitted <= 2;
|
||||
end
|
||||
|
||||
else if(bytes_transmitted == 2) begin
|
||||
axiod <= (buffer[11:8] < 10) ? (buffer[11:8] + 8'h30) : (buffer[11:8] + 8'h41 - 'd10);
|
||||
if (axior) bytes_transmitted <= 3;
|
||||
end
|
||||
|
||||
else if(bytes_transmitted == 3) begin
|
||||
axiod <= (buffer[7:4] < 10) ? (buffer[7:4] + 8'h30) : (buffer[7:4] + 8'h41 - 'd10);
|
||||
if (axior) bytes_transmitted <= 4;
|
||||
end
|
||||
|
||||
else if(bytes_transmitted == 4) begin
|
||||
axiod <= (buffer[3:0] < 10) ? (buffer[3:0] + 8'h30) : (buffer[3:0] + 8'h41 - 'd10);
|
||||
if (axior) bytes_transmitted <= 5;
|
||||
end
|
||||
|
||||
else if(bytes_transmitted == 5) begin
|
||||
axiod <= 8'h0D;
|
||||
if (axior) bytes_transmitted <= 6;
|
||||
end
|
||||
|
||||
else if(bytes_transmitted == 6) begin
|
||||
axiod <= 8'h0A;
|
||||
if (axior) begin
|
||||
axiov <= 0;
|
||||
bytes_transmitted <= 7;
|
||||
end
|
||||
end
|
||||
|
||||
else if(bytes_transmitted == 7) begin
|
||||
if(axior) begin
|
||||
res_ready <= 1;
|
||||
bytes_transmitted <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
`default_nettype wire
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
module bto7s(
|
||||
input wire [3:0] x_in,
|
||||
output logic [6:0] s_out);
|
||||
|
||||
logic sa, sb, sc, sd, se, sf, sg;
|
||||
assign s_out = {sg, sf, se, sd, sc, sb, sa};
|
||||
|
||||
// array of bits that are "one hot" with numbers 0 through 15
|
||||
logic [15:0] num;
|
||||
|
||||
assign num[0] = ~x_in[3] && ~x_in[2] && ~x_in[1] && ~x_in[0];
|
||||
assign num[1] = ~x_in[3] && ~x_in[2] && ~x_in[1] && x_in[0];
|
||||
assign num[2] = x_in == 4'd2;
|
||||
assign num[3] = x_in == 4'd3;
|
||||
assign num[4] = x_in == 4'd4;
|
||||
assign num[5] = x_in == 4'd5;
|
||||
assign num[6] = x_in == 4'd6;
|
||||
assign num[7] = x_in == 4'd7;
|
||||
assign num[8] = x_in == 4'd8;
|
||||
assign num[9] = x_in == 4'd9;
|
||||
assign num[10] = x_in == 4'd10;
|
||||
assign num[11] = x_in == 4'd11;
|
||||
assign num[12] = x_in == 4'd12;
|
||||
assign num[13] = x_in == 4'd13;
|
||||
assign num[14] = x_in == 4'd14;
|
||||
assign num[15] = x_in == 4'd15;
|
||||
|
||||
/* you could also do this with generation, like this:
|
||||
*
|
||||
* genvar i;
|
||||
* generate
|
||||
* for (i=0; i<16; i=i+1)begin
|
||||
* assign num[i] = (x_in == i);
|
||||
* end
|
||||
* endgenerate
|
||||
*/
|
||||
|
||||
/* assign the seven output segments, sa through sg, using a "sum of products"
|
||||
* approach and the diagram above.
|
||||
*/
|
||||
|
||||
assign sa = num[0] || num[2] || num[3] || num[5] || num[6] || num[7] || num[8] || num[9] || num[10] || num[12] ||num[14] ||num[15];
|
||||
assign sb = num[0] || num[1] || num[2] || num[3] || num[4] || num[7] || num[8] || num[9] || num[10] || num[13];
|
||||
assign sc = num[0] || num[1] || num[3] || num[4] || num[5] || num[6] || num[7] || num[8] || num[9] || num[10] || num[11] || num[13];
|
||||
assign sd = num[0] || num[2] || num[3] || num[5] || num[6] || num[8] || num[9] || num[11] || num[12] || num[13] || num[14];
|
||||
assign se = num[0] || num[2] || num[6] || num[8] || num[10] || num[11] || num[12] || num[13] || num[14] || num[15];
|
||||
assign sf = num[0] || num[4] || num[5] || num[6] || num[8] || num[9] || num[10] || num[11] || num[12] || num[14] || num[15];
|
||||
assign sg = num[2] || num[3] || num[4] || num[5] || num[6] || num[8] || num[9] || num[10] || num[11] || num[13] || num[14] ||num[15];
|
||||
endmodule
|
||||
|
|
@ -1,611 +0,0 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
/*
|
||||
This manta definition was autogenerated on 15 Feb 2023 at 11:06:14 by fischerm
|
||||
|
||||
If this breaks or if you've got dank formal verification memes,
|
||||
please contact fischerm [at] mit.edu.
|
||||
*/
|
||||
|
||||
`define IDLE 0
|
||||
`define ARM 1
|
||||
`define FILL 2
|
||||
`define DOWNLINK 3
|
||||
|
||||
`define ARM_BYTE 8'b00110000
|
||||
|
||||
module manta (
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
|
||||
/* Begin autogenerated probe definitions */
|
||||
input wire larry,
|
||||
input wire curly,
|
||||
input wire moe,
|
||||
input wire [3:0] shemp,
|
||||
/* End autogenerated probe definitions */
|
||||
|
||||
input wire rxd,
|
||||
output logic txd);
|
||||
|
||||
/* Begin autogenerated parameters */
|
||||
localparam SAMPLE_WIDTH = 7;
|
||||
localparam SAMPLE_DEPTH = 4096;
|
||||
|
||||
localparam DATA_WIDTH = 8;
|
||||
localparam BAUDRATE = 115200;
|
||||
localparam CLK_FREQ_HZ = 100000000;
|
||||
|
||||
logic trigger;
|
||||
assign trigger = (larry && curly && ~moe);
|
||||
|
||||
logic [SAMPLE_WIDTH - 1 : 0] concat;
|
||||
assign concat = {larry, curly, moe, shemp};
|
||||
/* End autogenerated parameters */
|
||||
|
||||
|
||||
// FIFO
|
||||
logic [7:0] fifo_data_in;
|
||||
logic fifo_input_ready;
|
||||
|
||||
logic fifo_request_output;
|
||||
logic [7:0] fifo_data_out;
|
||||
logic fifo_output_valid;
|
||||
|
||||
logic [11:0] fifo_size;
|
||||
logic fifo_empty;
|
||||
logic fifo_full;
|
||||
|
||||
fifo #(
|
||||
.WIDTH(SAMPLE_WIDTH),
|
||||
.DEPTH(SAMPLE_DEPTH)
|
||||
) fifo (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
|
||||
.data_in(fifo_data_in),
|
||||
.input_ready(fifo_input_ready),
|
||||
|
||||
.request_output(fifo_request_output),
|
||||
.data_out(fifo_data_out),
|
||||
.output_valid(fifo_output_valid),
|
||||
|
||||
.size(fifo_size),
|
||||
.empty(fifo_empty),
|
||||
.full(fifo_full));
|
||||
|
||||
// Serial interface
|
||||
logic tx_start;
|
||||
logic [7:0] tx_data;
|
||||
logic tx_busy;
|
||||
|
||||
logic [7:0] rx_data;
|
||||
logic rx_ready;
|
||||
logic rx_busy;
|
||||
|
||||
|
||||
uart_tx #(
|
||||
.DATA_WIDTH(DATA_WIDTH),
|
||||
.CLK_FREQ_HZ(CLK_FREQ_HZ),
|
||||
.BAUDRATE(BAUDRATE))
|
||||
tx (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.start(tx_start),
|
||||
.data(tx_data),
|
||||
|
||||
.busy(tx_busy),
|
||||
.txd(txd));
|
||||
|
||||
uart_rx #(
|
||||
.DATA_WIDTH(DATA_WIDTH),
|
||||
.CLK_FREQ_HZ(CLK_FREQ_HZ),
|
||||
.BAUDRATE(BAUDRATE))
|
||||
rx (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.rxd(rxd),
|
||||
|
||||
.data(rx_data),
|
||||
.ready(rx_ready),
|
||||
.busy(rx_busy));
|
||||
|
||||
|
||||
/* State Machine */
|
||||
/*
|
||||
|
||||
IDLE:
|
||||
- literally nothing is happening. the FIFO isn't being written to or read from. it should be empty.
|
||||
- an arm command over serial is what brings us into the ARM state
|
||||
|
||||
ARM:
|
||||
- popping things onto FIFO. if the fifo is halfway full, we pop them off too.
|
||||
- meeting the trigger condition is what moves us into the filing state
|
||||
|
||||
FILL:
|
||||
- popping things onto FIFO, until it's full. once it is full, we move into the downlinking state
|
||||
|
||||
DOWNLINK:
|
||||
- popping thing off of the FIFO until it's empty. once it's empty, we move back into the IDLE state
|
||||
*/
|
||||
|
||||
/* Downlink State Machine Controller */
|
||||
/*
|
||||
|
||||
- ila enters the downlink state
|
||||
- set fifo_output_request high for a clock cycle
|
||||
- when fifo_output_valid goes high, send fifo_data_out across the line
|
||||
- do nothing until tx_busy goes low
|
||||
- goto step 2
|
||||
|
||||
*/
|
||||
|
||||
logic [1:0] state;
|
||||
logic [2:0] downlink_fsm_state;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if(rst) begin
|
||||
state <= `IDLE;
|
||||
downlink_fsm_state <= 0;
|
||||
tx_data <= 0;
|
||||
tx_start <= 0;
|
||||
end
|
||||
else begin
|
||||
|
||||
case (state)
|
||||
`IDLE : begin
|
||||
fifo_input_ready <= 0;
|
||||
fifo_request_output <= 0;
|
||||
|
||||
if (rx_ready && rx_data == `ARM_BYTE) state <= `ARM;
|
||||
|
||||
end
|
||||
|
||||
`ARM : begin
|
||||
// place samples into FIFO
|
||||
fifo_input_ready <= 1;
|
||||
fifo_data_in <= concat;
|
||||
|
||||
// remove old samples if we're more than halfway full
|
||||
fifo_request_output <= (fifo_size >= SAMPLE_DEPTH / 2);
|
||||
|
||||
if(trigger) state <= `FILL;
|
||||
end
|
||||
|
||||
`FILL : begin
|
||||
// place samples into FIFO
|
||||
fifo_input_ready <= 1;
|
||||
fifo_data_in <= concat;
|
||||
|
||||
// don't pop anything out the FIFO
|
||||
fifo_request_output <= 0;
|
||||
|
||||
if(fifo_size == SAMPLE_DEPTH - 1) state <= `DOWNLINK;
|
||||
end
|
||||
|
||||
`DOWNLINK : begin
|
||||
// place no samples into FIFO
|
||||
fifo_input_ready <= 0;
|
||||
|
||||
|
||||
case (downlink_fsm_state)
|
||||
0 : begin
|
||||
if (~fifo_empty) begin
|
||||
fifo_request_output <= 1;
|
||||
downlink_fsm_state <= 1;
|
||||
end
|
||||
|
||||
else state <= `IDLE;
|
||||
end
|
||||
|
||||
1 : begin
|
||||
fifo_request_output <= 0;
|
||||
|
||||
if (fifo_output_valid) begin
|
||||
tx_data <= fifo_data_out;
|
||||
tx_start <= 1;
|
||||
downlink_fsm_state <= 2;
|
||||
end
|
||||
end
|
||||
|
||||
2 : begin
|
||||
tx_start <= 0;
|
||||
|
||||
if (~tx_busy && ~tx_start) downlink_fsm_state <= 0;
|
||||
end
|
||||
endcase
|
||||
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
`default_nettype wire`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module fifo (
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
|
||||
input wire [WIDTH - 1:0] data_in,
|
||||
input wire input_ready,
|
||||
|
||||
input wire request_output,
|
||||
output logic [WIDTH - 1:0] data_out,
|
||||
output logic output_valid,
|
||||
|
||||
output logic [AW:0] size,
|
||||
output logic empty,
|
||||
output logic full
|
||||
);
|
||||
|
||||
parameter WIDTH = 8;
|
||||
parameter DEPTH = 4096;
|
||||
localparam AW = $clog2(DEPTH);
|
||||
|
||||
logic [AW:0] write_pointer;
|
||||
logic [AW:0] read_pointer;
|
||||
|
||||
logic empty_int;
|
||||
assign empty_int = (write_pointer[AW] == read_pointer[AW]);
|
||||
|
||||
logic full_or_empty;
|
||||
assign full_or_empty = (write_pointer[AW-1:0] == read_pointer[AW-1:0]);
|
||||
|
||||
assign full = full_or_empty & !empty_int;
|
||||
assign empty = full_or_empty & empty_int;
|
||||
assign size = write_pointer - read_pointer;
|
||||
|
||||
logic output_valid_pip_0;
|
||||
logic output_valid_pip_1;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (input_ready && ~full)
|
||||
write_pointer <= write_pointer + 1'd1;
|
||||
|
||||
if (request_output && ~empty)
|
||||
read_pointer <= read_pointer + 1'd1;
|
||||
output_valid_pip_0 <= request_output;
|
||||
output_valid_pip_1 <= output_valid_pip_0;
|
||||
output_valid <= output_valid_pip_1;
|
||||
|
||||
if (rst) begin
|
||||
read_pointer <= 0;
|
||||
write_pointer <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
xilinx_true_dual_port_read_first_2_clock_ram #(
|
||||
.RAM_WIDTH(WIDTH),
|
||||
.RAM_DEPTH(DEPTH),
|
||||
.RAM_PERFORMANCE("HIGH_PERFORMANCE")
|
||||
|
||||
) buffer (
|
||||
|
||||
// write port
|
||||
.clka(clk),
|
||||
.rsta(rst),
|
||||
.ena(1),
|
||||
.addra(write_pointer),
|
||||
.dina(data_in),
|
||||
.wea(input_ready),
|
||||
.regcea(1),
|
||||
.douta(),
|
||||
|
||||
// read port
|
||||
.clkb(clk),
|
||||
.rstb(rst),
|
||||
.enb(1),
|
||||
.addrb(read_pointer),
|
||||
.dinb(),
|
||||
.web(0),
|
||||
.regceb(1),
|
||||
.doutb(data_out));
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
|
||||
module uart_tx(
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
input wire [DATA_WIDTH-1:0] data,
|
||||
input wire start,
|
||||
|
||||
output logic busy,
|
||||
output logic txd
|
||||
);
|
||||
|
||||
// Just going to stick to 8N1 for now, we'll come back and
|
||||
// parameterize this later.
|
||||
|
||||
parameter DATA_WIDTH = 8;
|
||||
parameter CLK_FREQ_HZ = 100_000_000;
|
||||
parameter BAUDRATE = 115200;
|
||||
|
||||
localparam PRESCALER = CLK_FREQ_HZ / BAUDRATE;
|
||||
|
||||
logic [$clog2(PRESCALER) - 1:0] baud_counter;
|
||||
logic [$clog2(DATA_WIDTH + 2):0] bit_index;
|
||||
logic [DATA_WIDTH - 1:0] data_buf;
|
||||
|
||||
// make secondary logic for baudrate
|
||||
always_ff @(posedge clk) begin
|
||||
if(rst) baud_counter <= 0;
|
||||
else begin
|
||||
baud_counter <= (baud_counter == PRESCALER - 1) ? 0 : baud_counter + 1;
|
||||
end
|
||||
end
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
|
||||
// reset logic
|
||||
if(rst) begin
|
||||
bit_index <= 0;
|
||||
busy <= 0;
|
||||
txd <= 1; // idle high
|
||||
end
|
||||
|
||||
// enter transmitting state logic
|
||||
// don't allow new requests to interrupt current
|
||||
// transfers
|
||||
if(start && ~busy) begin
|
||||
busy <= 1;
|
||||
data_buf <= data;
|
||||
end
|
||||
|
||||
|
||||
// transmitting state logic
|
||||
else if(baud_counter == 0 && busy) begin
|
||||
|
||||
if (bit_index == 0) begin
|
||||
txd <= 0;
|
||||
bit_index <= bit_index + 1;
|
||||
end
|
||||
|
||||
else if ((bit_index < DATA_WIDTH + 1) && (bit_index > 0)) begin
|
||||
txd <= data_buf[bit_index - 1];
|
||||
bit_index <= bit_index + 1;
|
||||
end
|
||||
|
||||
else if (bit_index == DATA_WIDTH + 1) begin
|
||||
txd <= 1;
|
||||
bit_index <= bit_index + 1;
|
||||
end
|
||||
|
||||
else if (bit_index >= DATA_WIDTH + 1) begin
|
||||
busy <= 0;
|
||||
bit_index <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
||||
`default_nettype wire
|
||||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module uart_rx(
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
input wire rxd,
|
||||
|
||||
output logic [DATA_WIDTH - 1:0] data,
|
||||
output logic ready,
|
||||
output logic busy
|
||||
);
|
||||
|
||||
// Just going to stick to 8N1 for now, we'll come back and
|
||||
// parameterize this later.
|
||||
|
||||
parameter DATA_WIDTH = 8;
|
||||
parameter CLK_FREQ_HZ = 100_000_000;
|
||||
parameter BAUDRATE = 115200;
|
||||
|
||||
localparam PRESCALER = CLK_FREQ_HZ / BAUDRATE;
|
||||
|
||||
logic [$clog2(PRESCALER) - 1:0] baud_counter;
|
||||
logic [$clog2(DATA_WIDTH + 2):0] bit_index;
|
||||
logic [DATA_WIDTH + 2 : 0] data_buf;
|
||||
|
||||
logic prev_rxd;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
prev_rxd <= rxd;
|
||||
ready <= 0;
|
||||
baud_counter <= (baud_counter == PRESCALER - 1) ? 0 : baud_counter + 1;
|
||||
|
||||
// reset logic
|
||||
if(rst) begin
|
||||
bit_index <= 0;
|
||||
data <= 0;
|
||||
busy <= 0;
|
||||
baud_counter <= 0;
|
||||
end
|
||||
|
||||
// start receiving if we see a falling edge, and not already busy
|
||||
else if (prev_rxd && ~rxd && ~busy) begin
|
||||
busy <= 1;
|
||||
data_buf <= 0;
|
||||
baud_counter <= 0;
|
||||
end
|
||||
|
||||
// if we're actually receiving
|
||||
else if (busy) begin
|
||||
if (baud_counter == PRESCALER / 2) begin
|
||||
data_buf[bit_index] <= rxd;
|
||||
bit_index <= bit_index + 1;
|
||||
|
||||
if (bit_index == DATA_WIDTH + 1) begin
|
||||
busy <= 0;
|
||||
bit_index <= 0;
|
||||
|
||||
|
||||
if (rxd && ~data_buf[0]) begin
|
||||
data <= data_buf[DATA_WIDTH : 1];
|
||||
ready <= 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
// Xilinx True Dual Port RAM, Read First, Dual Clock
|
||||
// This code implements a parameterizable true dual port memory (both ports can read and write).
|
||||
// The behavior of this RAM is when data is written, the prior memory contents at the write
|
||||
// address are presented on the output port. If the output data is
|
||||
// not needed during writes or the last read value is desired to be retained,
|
||||
// it is suggested to use a no change RAM as it is more power efficient.
|
||||
// If a reset or enable is not necessary, it may be tied off or removed from the code.
|
||||
|
||||
module xilinx_true_dual_port_read_first_2_clock_ram #(
|
||||
parameter RAM_WIDTH = 18, // Specify RAM data width
|
||||
parameter RAM_DEPTH = 1024, // Specify RAM depth (number of entries)
|
||||
parameter RAM_PERFORMANCE = "HIGH_PERFORMANCE", // Select "HIGH_PERFORMANCE" or "LOW_LATENCY"
|
||||
parameter INIT_FILE = "" // Specify name/location of RAM initialization file if using one (leave blank if not)
|
||||
) (
|
||||
input [clogb2(RAM_DEPTH-1)-1:0] addra, // Port A address bus, width determined from RAM_DEPTH
|
||||
input [clogb2(RAM_DEPTH-1)-1:0] addrb, // Port B address bus, width determined from RAM_DEPTH
|
||||
input [RAM_WIDTH-1:0] dina, // Port A RAM input data
|
||||
input [RAM_WIDTH-1:0] dinb, // Port B RAM input data
|
||||
input clka, // Port A clock
|
||||
input clkb, // Port B clock
|
||||
input wea, // Port A write enable
|
||||
input web, // Port B write enable
|
||||
input ena, // Port A RAM Enable, for additional power savings, disable port when not in use
|
||||
input enb, // Port B RAM Enable, for additional power savings, disable port when not in use
|
||||
input rsta, // Port A output reset (does not affect memory contents)
|
||||
input rstb, // Port B output reset (does not affect memory contents)
|
||||
input regcea, // Port A output register enable
|
||||
input regceb, // Port B output register enable
|
||||
output [RAM_WIDTH-1:0] douta, // Port A RAM output data
|
||||
output [RAM_WIDTH-1:0] doutb // Port B RAM output data
|
||||
);
|
||||
|
||||
reg [RAM_WIDTH-1:0] BRAM [RAM_DEPTH-1:0];
|
||||
reg [RAM_WIDTH-1:0] ram_data_a = {RAM_WIDTH{1'b0}};
|
||||
reg [RAM_WIDTH-1:0] ram_data_b = {RAM_WIDTH{1'b0}};
|
||||
|
||||
//this loop below allows for rendering with iverilog simulations!
|
||||
/*
|
||||
integer idx;
|
||||
for(idx = 0; idx < RAM_DEPTH; idx = idx+1) begin: cats
|
||||
wire [RAM_WIDTH-1:0] tmp;
|
||||
assign tmp = BRAM[idx];
|
||||
end
|
||||
*/
|
||||
|
||||
// The following code either initializes the memory values to a specified file or to all zeros to match hardware
|
||||
generate
|
||||
if (INIT_FILE != "") begin: use_init_file
|
||||
initial
|
||||
$readmemh(INIT_FILE, BRAM, 0, RAM_DEPTH-1);
|
||||
end else begin: init_bram_to_zero
|
||||
integer ram_index;
|
||||
initial
|
||||
for (ram_index = 0; ram_index < RAM_DEPTH; ram_index = ram_index + 1)
|
||||
BRAM[ram_index] = {RAM_WIDTH{1'b0}};
|
||||
end
|
||||
endgenerate
|
||||
integer idx;
|
||||
// initial begin
|
||||
// for (idx = 0; idx < RAM_DEPTH; idx = idx + 1) begin
|
||||
// $dumpvars(0, BRAM[idx]);
|
||||
// end
|
||||
// end
|
||||
always @(posedge clka)
|
||||
if (ena) begin
|
||||
if (wea)
|
||||
BRAM[addra] <= dina;
|
||||
ram_data_a <= BRAM[addra];
|
||||
end
|
||||
|
||||
always @(posedge clkb)
|
||||
if (enb) begin
|
||||
if (web)
|
||||
BRAM[addrb] <= dinb;
|
||||
ram_data_b <= BRAM[addrb];
|
||||
end
|
||||
|
||||
// The following code generates HIGH_PERFORMANCE (use output register) or LOW_LATENCY (no output register)
|
||||
generate
|
||||
if (RAM_PERFORMANCE == "LOW_LATENCY") begin: no_output_register
|
||||
|
||||
// The following is a 1 clock cycle read latency at the cost of a longer clock-to-out timing
|
||||
assign douta = ram_data_a;
|
||||
assign doutb = ram_data_b;
|
||||
|
||||
end else begin: output_register
|
||||
|
||||
// The following is a 2 clock cycle read latency with improve clock-to-out timing
|
||||
|
||||
reg [RAM_WIDTH-1:0] douta_reg = {RAM_WIDTH{1'b0}};
|
||||
reg [RAM_WIDTH-1:0] doutb_reg = {RAM_WIDTH{1'b0}};
|
||||
|
||||
always @(posedge clka)
|
||||
if (rsta)
|
||||
douta_reg <= {RAM_WIDTH{1'b0}};
|
||||
else if (regcea)
|
||||
douta_reg <= ram_data_a;
|
||||
|
||||
always @(posedge clkb)
|
||||
if (rstb)
|
||||
doutb_reg <= {RAM_WIDTH{1'b0}};
|
||||
else if (regceb)
|
||||
doutb_reg <= ram_data_b;
|
||||
|
||||
assign douta = douta_reg;
|
||||
assign doutb = doutb_reg;
|
||||
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// The following function calculates the address width based on specified RAM depth
|
||||
function integer clogb2;
|
||||
input integer depth;
|
||||
for (clogb2=0; depth>0; clogb2=clogb2+1)
|
||||
depth = depth >> 1;
|
||||
endfunction
|
||||
|
||||
endmodule
|
||||
|
||||
// The following is an instantiation template for xilinx_true_dual_port_read_first_2_clock_ram
|
||||
/*
|
||||
// Xilinx True Dual Port RAM, Read First, Dual Clock
|
||||
xilinx_true_dual_port_read_first_2_clock_ram #(
|
||||
.RAM_WIDTH(18), // Specify RAM data width
|
||||
.RAM_DEPTH(1024), // Specify RAM depth (number of entries)
|
||||
.RAM_PERFORMANCE("HIGH_PERFORMANCE"), // Select "HIGH_PERFORMANCE" or "LOW_LATENCY"
|
||||
.INIT_FILE("") // Specify name/location of RAM initialization file if using one (leave blank if not)
|
||||
) your_instance_name (
|
||||
.addra(addra), // Port A address bus, width determined from RAM_DEPTH
|
||||
.addrb(addrb), // Port B address bus, width determined from RAM_DEPTH
|
||||
.dina(dina), // Port A RAM input data, width determined from RAM_WIDTH
|
||||
.dinb(dinb), // Port B RAM input data, width determined from RAM_WIDTH
|
||||
.clka(clka), // Port A clock
|
||||
.clkb(clkb), // Port B clock
|
||||
.wea(wea), // Port A write enable
|
||||
.web(web), // Port B write enable
|
||||
.ena(ena), // Port A RAM Enable, for additional power savings, disable port when not in use
|
||||
.enb(enb), // Port B RAM Enable, for additional power savings, disable port when not in use
|
||||
.rsta(rsta), // Port A output reset (does not affect memory contents)
|
||||
.rstb(rstb), // Port B output reset (does not affect memory contents)
|
||||
.regcea(regcea), // Port A output register enable
|
||||
.regceb(regceb), // Port B output register enable
|
||||
.douta(douta), // Port A RAM output data, width determined from RAM_WIDTH
|
||||
.doutb(doutb) // Port B RAM output data, width determined from RAM_WIDTH
|
||||
);
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
`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;
|
||||
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) mem[addr_i - BASE_ADDR] <= wdata_i;
|
||||
else rdata_o <= mem[addr_i - BASE_ADDR];
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns/1ps
|
||||
|
||||
module manta(
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
input wire rxd,
|
||||
output reg txd
|
||||
);
|
||||
|
||||
// tb --> uart_rx signals
|
||||
// uart_rx #(
|
||||
// .DATA_WIDTH(8),
|
||||
// .CLK_FREQ_HZ(100_000_000),
|
||||
// .BAUDRATE(115200)
|
||||
// ) urx (
|
||||
// .clk(clk),
|
||||
// .rst(rst),
|
||||
// .rxd(rxd),
|
||||
|
||||
// .axiod(urx_brx_axid),
|
||||
// .axiov(urx_brx_axiv));
|
||||
|
||||
rxuart urx(
|
||||
.i_clk(clk),
|
||||
.i_uart_rx(rxd),
|
||||
.o_wr(urx_brx_axiv),
|
||||
.o_data(urx_brx_axid));
|
||||
|
||||
// uart_rx --> bridge_rx signals
|
||||
logic [7:0] urx_brx_axid;
|
||||
logic urx_brx_axiv;
|
||||
|
||||
bridge_rx brx (
|
||||
.clk(clk),
|
||||
.axiid(urx_brx_axid),
|
||||
.axiiv(urx_brx_axiv),
|
||||
|
||||
.req_addr(brx_mem_1_addr),
|
||||
.req_data(brx_mem_1_wdata),
|
||||
.req_rw(brx_mem_1_rw),
|
||||
.req_valid(brx_mem_1_valid),
|
||||
.req_ready(1'b1));
|
||||
|
||||
// bridge_rx --> mem_1 signals
|
||||
logic [15:0] brx_mem_1_addr;
|
||||
logic [15:0] brx_mem_1_wdata;
|
||||
logic brx_mem_1_rw;
|
||||
logic brx_mem_1_valid;
|
||||
|
||||
lut_mem #(
|
||||
.DEPTH(8),
|
||||
.BASE_ADDR(0)
|
||||
) mem_1 (
|
||||
.clk(clk),
|
||||
.addr_i(brx_mem_1_addr),
|
||||
.wdata_i(brx_mem_1_wdata),
|
||||
.rdata_i(0),
|
||||
.rw_i(brx_mem_1_rw),
|
||||
.valid_i(brx_mem_1_valid),
|
||||
|
||||
.addr_o(),
|
||||
.wdata_o(),
|
||||
.rdata_o(mem_1_btx_rdata),
|
||||
.rw_o(),
|
||||
.valid_o(mem_1_btx_valid));
|
||||
|
||||
logic [15:0] mem_1_btx_rdata;
|
||||
logic mem_1_btx_valid;
|
||||
|
||||
bridge_tx btx (
|
||||
.clk(clk),
|
||||
|
||||
.res_data(mem_1_btx_rdata),
|
||||
.res_valid(mem_1_btx_valid),
|
||||
.res_ready(),
|
||||
|
||||
.axiod(btx_utx_axid),
|
||||
.axiov(btx_utx_axiv),
|
||||
.axior(btx_utx_axir));
|
||||
|
||||
// bridge_tx --> uart_tx signals
|
||||
logic [7:0] btx_utx_axid;
|
||||
logic btx_utx_axiv;
|
||||
logic btx_utx_axir;
|
||||
|
||||
uart_tx #(
|
||||
.DATA_WIDTH(8),
|
||||
.CLK_FREQ_HZ(100_000_000),
|
||||
.BAUDRATE(115200)
|
||||
) utx (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
|
||||
.axiid(btx_utx_axid),
|
||||
.axiiv(btx_utx_axiv),
|
||||
.axiir(btx_utx_axir),
|
||||
|
||||
.txd(txd));
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
//
|
||||
`default_nettype none
|
||||
|
||||
module rxuart(
|
||||
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
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
module seven_segment_controller #(parameter COUNT_TO = 100000)
|
||||
( input wire clk_in,
|
||||
input wire rst_in,
|
||||
input wire [31:0] val_in,
|
||||
output logic[6:0] cat_out,
|
||||
output logic[7:0] an_out
|
||||
);
|
||||
|
||||
logic[7:0] segment_state;
|
||||
logic[31:0] segment_counter;
|
||||
logic [3:0] routed_vals;
|
||||
logic [6:0] led_out;
|
||||
|
||||
bto7s mbto7s (.x_in(routed_vals), .s_out(led_out));
|
||||
|
||||
assign cat_out = ~led_out;
|
||||
assign an_out = ~segment_state;
|
||||
|
||||
always_comb begin
|
||||
case(segment_state)
|
||||
8'b0000_0001: routed_vals = val_in[3:0];
|
||||
8'b0000_0010: routed_vals = val_in[7:4];
|
||||
8'b0000_0100: routed_vals = val_in[11:8];
|
||||
8'b0000_1000: routed_vals = val_in[15:12];
|
||||
8'b0001_0000: routed_vals = val_in[19:16];
|
||||
8'b0010_0000: routed_vals = val_in[23:20];
|
||||
8'b0100_0000: routed_vals = val_in[27:24];
|
||||
8'b1000_0000: routed_vals = val_in[31:28];
|
||||
default: routed_vals = val_in[3:0];
|
||||
endcase
|
||||
end
|
||||
always_ff @(posedge clk_in)begin
|
||||
if (rst_in)begin
|
||||
segment_state <= 8'b0000_0001;
|
||||
segment_counter <= 32'b0;
|
||||
end else begin
|
||||
if (segment_counter == COUNT_TO)begin
|
||||
segment_counter <= 32'd0;
|
||||
segment_state <= {segment_state[6:0],segment_state[7]};
|
||||
end else begin
|
||||
segment_counter <= segment_counter +1;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule //seven_segment_controller
|
||||
|
|
@ -4,29 +4,36 @@
|
|||
module top_level (
|
||||
input wire clk,
|
||||
input wire btnc,
|
||||
input wire btnu,
|
||||
input wire [15:0] sw,
|
||||
|
||||
output logic [15:0] led,
|
||||
output logic ca, cb, cc, cd, ce, cf, cg,
|
||||
output logic [7:0] an,
|
||||
|
||||
input wire uart_txd_in,
|
||||
output logic uart_rxd_out
|
||||
);
|
||||
|
||||
// Signal Generator
|
||||
logic [7:0] count;
|
||||
always_ff @(posedge clk) count <= count + 1;
|
||||
|
||||
// debugger
|
||||
// // Signal Generator
|
||||
// logic [7:0] count;
|
||||
// always_ff @(posedge clk) count <= count + 1;
|
||||
|
||||
manta manta(
|
||||
.clk(clk),
|
||||
.rst(btnc),
|
||||
.larry(count[0]),
|
||||
.curly(count[1]),
|
||||
.moe(count[2]),
|
||||
.shemp(count[3:0]),
|
||||
|
||||
.rxd(uart_txd_in),
|
||||
.txd(uart_rxd_out));
|
||||
.txd(uart_rxd_out)
|
||||
);
|
||||
|
||||
assign led = manta.brx_mem_1_addr;
|
||||
|
||||
logic [6:0] cat;
|
||||
assign {cg,cf,ce,cd,cc,cb,ca} = cat;
|
||||
seven_segment_controller ss (
|
||||
.clk_in(clk),
|
||||
.rst_in(btnc),
|
||||
.val_in( (manta.mem_1_btx_rdata << 16) | (manta.brx_mem_1_wdata) ),
|
||||
.cat_out(cat),
|
||||
.an_out(an));
|
||||
|
||||
endmodule
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,69 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module uart_rx(
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
input wire rxd,
|
||||
|
||||
output reg [DATA_WIDTH - 1:0] axiod,
|
||||
output reg axiov
|
||||
);
|
||||
|
||||
parameter DATA_WIDTH = 0;
|
||||
parameter CLK_FREQ_HZ = 0;
|
||||
parameter BAUDRATE = 0;
|
||||
|
||||
localparam BAUD_PERIOD = CLK_FREQ_HZ / BAUDRATE;
|
||||
|
||||
reg [$clog2(BAUD_PERIOD) - 1:0] baud_counter;
|
||||
reg [$clog2(DATA_WIDTH + 2):0] bit_index;
|
||||
reg [DATA_WIDTH + 2 : 0] data_buf;
|
||||
|
||||
reg prev_rxd;
|
||||
reg busy;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
prev_rxd <= rxd;
|
||||
axiov <= 0;
|
||||
baud_counter <= (baud_counter == BAUD_PERIOD - 1) ? 0 : baud_counter + 1;
|
||||
|
||||
// reset logic
|
||||
if(rst) begin
|
||||
bit_index <= 0;
|
||||
axiod <= 0;
|
||||
busy <= 0;
|
||||
baud_counter <= 0;
|
||||
end
|
||||
|
||||
// start receiving if we see a falling edge, and not already busy
|
||||
else if (prev_rxd && ~rxd && ~busy) begin
|
||||
busy <= 1;
|
||||
data_buf <= 0;
|
||||
baud_counter <= 0;
|
||||
end
|
||||
|
||||
// if we're actually receiving
|
||||
else if (busy) begin
|
||||
if (baud_counter == BAUD_PERIOD / 2) begin
|
||||
data_buf[bit_index] <= rxd;
|
||||
bit_index <= bit_index + 1;
|
||||
|
||||
if (bit_index == DATA_WIDTH + 1) begin
|
||||
busy <= 0;
|
||||
bit_index <= 0;
|
||||
|
||||
|
||||
if (rxd && ~data_buf[0]) begin
|
||||
axiod <= data_buf[DATA_WIDTH : 1];
|
||||
axiov <= 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
`default_nettype none
|
||||
`timescale 1ns / 1ps
|
||||
|
||||
module uart_tx(
|
||||
input wire clk,
|
||||
input wire rst,
|
||||
|
||||
input wire [DATA_WIDTH-1:0] axiid,
|
||||
input wire axiiv,
|
||||
output reg axiir,
|
||||
|
||||
output reg txd
|
||||
);
|
||||
|
||||
parameter DATA_WIDTH = 0;
|
||||
parameter CLK_FREQ_HZ = 0;
|
||||
parameter BAUDRATE = 0;
|
||||
|
||||
localparam BAUD_PERIOD = CLK_FREQ_HZ / BAUDRATE;
|
||||
|
||||
reg busy;
|
||||
assign axiir = ~busy;
|
||||
|
||||
reg [$clog2(BAUD_PERIOD) - 1:0] baud_counter;
|
||||
reg [$clog2(DATA_WIDTH + 2):0] bit_index;
|
||||
reg [DATA_WIDTH - 1:0] data_buf;
|
||||
|
||||
// make secondary logic for baudrate
|
||||
always @(posedge clk) begin
|
||||
if(rst) baud_counter <= 0;
|
||||
else begin
|
||||
baud_counter <= (baud_counter == BAUD_PERIOD - 1) ? 0 : baud_counter + 1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
|
||||
// reset logic
|
||||
if(rst) begin
|
||||
bit_index <= 0;
|
||||
busy <= 0;
|
||||
txd <= 1; // idle high
|
||||
end
|
||||
|
||||
// enter transmitting state logic
|
||||
// don't allow new requests to interrupt current
|
||||
// transfers
|
||||
if(axiiv && ~busy) begin
|
||||
busy <= 1;
|
||||
data_buf <= axiid;
|
||||
end
|
||||
|
||||
|
||||
// transmitting state logic
|
||||
else if(baud_counter == 0 && busy) begin
|
||||
|
||||
if (bit_index == 0) begin
|
||||
txd <= 0;
|
||||
bit_index <= bit_index + 1;
|
||||
end
|
||||
|
||||
else if ((bit_index < DATA_WIDTH + 1) && (bit_index > 0)) begin
|
||||
txd <= data_buf[bit_index - 1];
|
||||
bit_index <= bit_index + 1;
|
||||
end
|
||||
|
||||
else if (bit_index == DATA_WIDTH + 1) begin
|
||||
txd <= 1;
|
||||
bit_index <= bit_index + 1;
|
||||
end
|
||||
|
||||
else if (bit_index >= DATA_WIDTH + 1) begin
|
||||
busy <= 0;
|
||||
bit_index <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
||||
`default_nettype wire
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import serial
|
||||
from time import sleep
|
||||
|
||||
with serial.Serial("/dev/tty.usbserial-210292AE39A41", 115200) as ser:
|
||||
for i in range(8):
|
||||
req = '{:04X}'.format(i)
|
||||
req = f"M{req}0000\r\n "
|
||||
req = req.encode('ascii')
|
||||
|
||||
ser.write(req)
|
||||
print(f"req --> {req}")
|
||||
sleep(0.1)
|
||||
|
|
@ -17,22 +17,22 @@ create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports {cl
|
|||
|
||||
##Switches
|
||||
|
||||
set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { sw[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
|
||||
set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { sw[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
|
||||
set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { sw[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
|
||||
set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { sw[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]
|
||||
set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { sw[4] }]; #IO_L12N_T1_MRCC_14 Sch=sw[4]
|
||||
set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { sw[5] }]; #IO_L7N_T1_D10_14 Sch=sw[5]
|
||||
set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { sw[6] }]; #IO_L17N_T2_A13_D29_14 Sch=sw[6]
|
||||
set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { sw[7] }]; #IO_L5N_T0_D07_14 Sch=sw[7]
|
||||
set_property -dict { PACKAGE_PIN T8 IOSTANDARD LVCMOS18 } [get_ports { sw[8] }]; #IO_L24N_T3_34 Sch=sw[8]
|
||||
set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS18 } [get_ports { sw[9] }]; #IO_25_34 Sch=sw[9]
|
||||
set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { sw[10] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=sw[10]
|
||||
set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { sw[11] }]; #IO_L23P_T3_A03_D19_14 Sch=sw[11]
|
||||
set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { sw[12] }]; #IO_L24P_T3_35 Sch=sw[12]
|
||||
set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { sw[13] }]; #IO_L20P_T3_A08_D24_14 Sch=sw[13]
|
||||
set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { sw[14] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=sw[14]
|
||||
set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { sw[15] }]; #IO_L21P_T3_DQS_14 Sch=sw[15]
|
||||
# set_property -dict { PACKAGE_PIN J15 IOSTANDARD LVCMOS33 } [get_ports { sw[0] }]; #IO_L24N_T3_RS0_15 Sch=sw[0]
|
||||
# set_property -dict { PACKAGE_PIN L16 IOSTANDARD LVCMOS33 } [get_ports { sw[1] }]; #IO_L3N_T0_DQS_EMCCLK_14 Sch=sw[1]
|
||||
# set_property -dict { PACKAGE_PIN M13 IOSTANDARD LVCMOS33 } [get_ports { sw[2] }]; #IO_L6N_T0_D08_VREF_14 Sch=sw[2]
|
||||
# set_property -dict { PACKAGE_PIN R15 IOSTANDARD LVCMOS33 } [get_ports { sw[3] }]; #IO_L13N_T2_MRCC_14 Sch=sw[3]
|
||||
# set_property -dict { PACKAGE_PIN R17 IOSTANDARD LVCMOS33 } [get_ports { sw[4] }]; #IO_L12N_T1_MRCC_14 Sch=sw[4]
|
||||
# set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { sw[5] }]; #IO_L7N_T1_D10_14 Sch=sw[5]
|
||||
# set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { sw[6] }]; #IO_L17N_T2_A13_D29_14 Sch=sw[6]
|
||||
# set_property -dict { PACKAGE_PIN R13 IOSTANDARD LVCMOS33 } [get_ports { sw[7] }]; #IO_L5N_T0_D07_14 Sch=sw[7]
|
||||
# set_property -dict { PACKAGE_PIN T8 IOSTANDARD LVCMOS18 } [get_ports { sw[8] }]; #IO_L24N_T3_34 Sch=sw[8]
|
||||
# set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS18 } [get_ports { sw[9] }]; #IO_25_34 Sch=sw[9]
|
||||
# set_property -dict { PACKAGE_PIN R16 IOSTANDARD LVCMOS33 } [get_ports { sw[10] }]; #IO_L15P_T2_DQS_RDWR_B_14 Sch=sw[10]
|
||||
# set_property -dict { PACKAGE_PIN T13 IOSTANDARD LVCMOS33 } [get_ports { sw[11] }]; #IO_L23P_T3_A03_D19_14 Sch=sw[11]
|
||||
# set_property -dict { PACKAGE_PIN H6 IOSTANDARD LVCMOS33 } [get_ports { sw[12] }]; #IO_L24P_T3_35 Sch=sw[12]
|
||||
# set_property -dict { PACKAGE_PIN U12 IOSTANDARD LVCMOS33 } [get_ports { sw[13] }]; #IO_L20P_T3_A08_D24_14 Sch=sw[13]
|
||||
# set_property -dict { PACKAGE_PIN U11 IOSTANDARD LVCMOS33 } [get_ports { sw[14] }]; #IO_L19N_T3_A09_D25_VREF_14 Sch=sw[14]
|
||||
# set_property -dict { PACKAGE_PIN V10 IOSTANDARD LVCMOS33 } [get_ports { sw[15] }]; #IO_L21P_T3_DQS_14 Sch=sw[15]
|
||||
|
||||
|
||||
## LEDs
|
||||
|
|
@ -64,24 +64,24 @@ set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { led[15
|
|||
|
||||
##7 segment display
|
||||
|
||||
#set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { ca }]; #IO_L24N_T3_A00_D16_14 Sch=ca
|
||||
#set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 } [get_ports { cb }]; #IO_25_14 Sch=cb
|
||||
#set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { cc }]; #IO_25_15 Sch=cc
|
||||
#set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports { cd }]; #IO_L17P_T2_A26_15 Sch=cd
|
||||
#set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { ce }]; #IO_L13P_T2_MRCC_14 Sch=ce
|
||||
#set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { cf }]; #IO_L19P_T3_A10_D26_14 Sch=cf
|
||||
#set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { cg }]; #IO_L4P_T0_D04_14 Sch=cg
|
||||
set_property -dict { PACKAGE_PIN T10 IOSTANDARD LVCMOS33 } [get_ports { ca }]; #IO_L24N_T3_A00_D16_14 Sch=ca
|
||||
set_property -dict { PACKAGE_PIN R10 IOSTANDARD LVCMOS33 } [get_ports { cb }]; #IO_25_14 Sch=cb
|
||||
set_property -dict { PACKAGE_PIN K16 IOSTANDARD LVCMOS33 } [get_ports { cc }]; #IO_25_15 Sch=cc
|
||||
set_property -dict { PACKAGE_PIN K13 IOSTANDARD LVCMOS33 } [get_ports { cd }]; #IO_L17P_T2_A26_15 Sch=cd
|
||||
set_property -dict { PACKAGE_PIN P15 IOSTANDARD LVCMOS33 } [get_ports { ce }]; #IO_L13P_T2_MRCC_14 Sch=ce
|
||||
set_property -dict { PACKAGE_PIN T11 IOSTANDARD LVCMOS33 } [get_ports { cf }]; #IO_L19P_T3_A10_D26_14 Sch=cf
|
||||
set_property -dict { PACKAGE_PIN L18 IOSTANDARD LVCMOS33 } [get_ports { cg }]; #IO_L4P_T0_D04_14 Sch=cg
|
||||
|
||||
#set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { dp }]; #IO_L19N_T3_A21_VREF_15 Sch=dp
|
||||
# set_property -dict { PACKAGE_PIN H15 IOSTANDARD LVCMOS33 } [get_ports { dp }]; #IO_L19N_T3_A21_VREF_15 Sch=dp
|
||||
|
||||
#set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { an[0] }]; #IO_L23P_T3_FOE_B_15 Sch=an[0]
|
||||
#set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { an[1] }]; #IO_L23N_T3_FWE_B_15 Sch=an[1]
|
||||
#set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { an[2] }]; #IO_L24P_T3_A01_D17_14 Sch=an[2]
|
||||
#set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { an[3] }]; #IO_L19P_T3_A22_15 Sch=an[3]
|
||||
#set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { an[4] }]; #IO_L8N_T1_D12_14 Sch=an[4]
|
||||
#set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { an[5] }]; #IO_L14P_T2_SRCC_14 Sch=an[5]
|
||||
#set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { an[6] }]; #IO_L23P_T3_35 Sch=an[6]
|
||||
#set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { an[7] }]; #IO_L23N_T3_A02_D18_14 Sch=an[7]
|
||||
set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { an[0] }]; #IO_L23P_T3_FOE_B_15 Sch=an[0]
|
||||
set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { an[1] }]; #IO_L23N_T3_FWE_B_15 Sch=an[1]
|
||||
set_property -dict { PACKAGE_PIN T9 IOSTANDARD LVCMOS33 } [get_ports { an[2] }]; #IO_L24P_T3_A01_D17_14 Sch=an[2]
|
||||
set_property -dict { PACKAGE_PIN J14 IOSTANDARD LVCMOS33 } [get_ports { an[3] }]; #IO_L19P_T3_A22_15 Sch=an[3]
|
||||
set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { an[4] }]; #IO_L8N_T1_D12_14 Sch=an[4]
|
||||
set_property -dict { PACKAGE_PIN T14 IOSTANDARD LVCMOS33 } [get_ports { an[5] }]; #IO_L14P_T2_SRCC_14 Sch=an[5]
|
||||
set_property -dict { PACKAGE_PIN K2 IOSTANDARD LVCMOS33 } [get_ports { an[6] }]; #IO_L23P_T3_35 Sch=an[6]
|
||||
set_property -dict { PACKAGE_PIN U13 IOSTANDARD LVCMOS33 } [get_ports { an[7] }]; #IO_L23N_T3_A02_D18_14 Sch=an[7]
|
||||
|
||||
|
||||
##Buttons
|
||||
|
|
@ -89,7 +89,7 @@ set_property -dict { PACKAGE_PIN V11 IOSTANDARD LVCMOS33 } [get_ports { led[15
|
|||
#set_property -dict { PACKAGE_PIN C12 IOSTANDARD LVCMOS33 } [get_ports { cpu_resetn }]; #IO_L3P_T0_DQS_AD1P_15 Sch=cpu_resetn
|
||||
|
||||
set_property -dict { PACKAGE_PIN N17 IOSTANDARD LVCMOS33 } [get_ports { btnc }]; #IO_L9P_T1_DQS_14 Sch=btnc
|
||||
set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { btnu }]; #IO_L4N_T0_D05_14 Sch=btnu
|
||||
#set_property -dict { PACKAGE_PIN M18 IOSTANDARD LVCMOS33 } [get_ports { btnu }]; #IO_L4N_T0_D05_14 Sch=btnu
|
||||
#set_property -dict { PACKAGE_PIN P17 IOSTANDARD LVCMOS33 } [get_ports { btnl }]; #IO_L12P_T1_MRCC_14 Sch=btnl
|
||||
#set_property -dict { PACKAGE_PIN M17 IOSTANDARD LVCMOS33 } [get_ports { btnr }]; #IO_L10N_T1_D15_14 Sch=btnr
|
||||
#set_property -dict { PACKAGE_PIN P18 IOSTANDARD LVCMOS33 } [get_ports { btnd }]; #IO_L9N_T1_DQS_D13_14 Sch=btnd
|
||||
|
|
|
|||
Loading…
Reference in New Issue