diff --git a/examples/nexys_a7/single_lut_ram/src/bridge_rx.v b/examples/nexys_a7/single_lut_ram/src/bridge_rx.v deleted file mode 100644 index 4e6c8f8..0000000 --- a/examples/nexys_a7/single_lut_ram/src/bridge_rx.v +++ /dev/null @@ -1,129 +0,0 @@ -`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 \ No newline at end of file diff --git a/examples/nexys_a7/single_lut_ram/src/bridge_tx.v b/examples/nexys_a7/single_lut_ram/src/bridge_tx.v deleted file mode 100644 index 7376739..0000000 --- a/examples/nexys_a7/single_lut_ram/src/bridge_tx.v +++ /dev/null @@ -1,72 +0,0 @@ -`default_nettype none -`timescale 1ns/1ps - -module bridge_tx( - input wire clk, - - input wire [15:0] rdata_i, - input wire rw_i, - input wire valid_i, - input wire ready_i, - - output reg [7:0] data_o, - 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 -`default_nettype wire \ No newline at end of file diff --git a/examples/nexys_a7/single_lut_ram/src/lut_mem.v b/examples/nexys_a7/single_lut_ram/src/lut_mem.v deleted file mode 100644 index c0e596a..0000000 --- a/examples/nexys_a7/single_lut_ram/src/lut_mem.v +++ /dev/null @@ -1,47 +0,0 @@ -`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 \ No newline at end of file diff --git a/examples/nexys_a7/single_lut_ram/src/manta.v b/examples/nexys_a7/single_lut_ram/src/manta.v index 6e48196..ca3b57d 100644 --- a/examples/nexys_a7/single_lut_ram/src/manta.v +++ b/examples/nexys_a7/single_lut_ram/src/manta.v @@ -1,68 +1,71 @@ `default_nettype none `timescale 1ns/1ps -module manta( +/* +This manta definition was generated on 09 Mar 2023 at 23:58:38 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 rst, - input wire rxd, - output reg txd); + + input wire rx, + output reg tx); rx_uart #(.CLOCKS_PER_BAUD(868)) urx ( .i_clk(clk), - .i_uart_rx(rxd), + .i_uart_rx(rx), .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), + .rx_data(urx_brx_axid), + .rx_valid(urx_brx_axiv), - .req_addr(brx_mem_addr), - .req_data(brx_mem_wdata), - .req_rw(brx_mem_rw), - .req_valid(brx_mem_valid), - .req_ready(1'b1)); + .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; - // bridge_rx --> mem signals - logic [15:0] brx_mem_addr; - logic [15:0] brx_mem_wdata; - logic brx_mem_rw; - logic brx_mem_valid; - - lut_mem #( - .DEPTH(32), - .BASE_ADDR(0) - ) mem ( + lut_mem my_logic_analyzer( .clk(clk), - .addr_i(brx_mem_addr), - .wdata_i(brx_mem_wdata), - .rdata_i(16'h0), - .rw_i(brx_mem_rw), - .valid_i(brx_mem_valid), + .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), + .addr_o(), .wdata_o(), - .rdata_o(mem_btx_rdata), - .rw_o(mem_btx_rw), - .valid_o(mem_btx_valid)); - - // mem --> frizzle signals, it's frizzle because that's a bus you wanna get off of - logic [15:0] mem_btx_rdata; - logic mem_btx_rw; - logic mem_btx_valid; + .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(mem_btx_rdata), - .rw_i(mem_btx_rw), - .valid_i(mem_btx_valid), + .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), @@ -79,7 +82,456 @@ module manta( .valid(btx_utx_valid), .ready(utx_btx_ready), - .tx(txd)); + .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 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 \ No newline at end of file diff --git a/examples/nexys_a7/single_lut_ram/src/rx_uart.v b/examples/nexys_a7/single_lut_ram/src/rx_uart.v deleted file mode 100644 index 1206348..0000000 --- a/examples/nexys_a7/single_lut_ram/src/rx_uart.v +++ /dev/null @@ -1,117 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// 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 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 diff --git a/examples/nexys_a7/single_lut_ram/src/top_level.sv b/examples/nexys_a7/single_lut_ram/src/top_level.sv index f8dc8a5..66caeda 100644 --- a/examples/nexys_a7/single_lut_ram/src/top_level.sv +++ b/examples/nexys_a7/single_lut_ram/src/top_level.sv @@ -13,25 +13,25 @@ module top_level ( output logic uart_rxd_out ); - // // Signal Generator + // Signal Generator // logic [7:0] count; // always_ff @(posedge clk) count <= count + 1; - manta manta( - .clk(clk), - .rst(btnc), - .rxd(uart_txd_in), - .txd(uart_rxd_out) - ); - assign led = manta.brx_mem_addr; + manta manta ( + .clk(clk), + + .rx(uart_txd_in), + .tx(uart_rxd_out)); + + assign led = manta.brx_my_logic_analyzer_addr; logic [6:0] cat; assign {cg,cf,ce,cd,cc,cb,ca} = cat; ssd ssd ( .clk_in(clk), .rst_in(btnc), - .val_in( (manta.mem_btx_rdata << 16) | (manta.brx_mem_wdata) ), + .val_in( (manta.my_logic_analyzer_btx_rdata << 16) | (manta.brx_my_logic_analyzer_wdata) ), .cat_out(cat), .an_out(an)); diff --git a/examples/nexys_a7/single_lut_ram/src/tx_uart.v b/examples/nexys_a7/single_lut_ram/src/tx_uart.v deleted file mode 100644 index eb5ed0d..0000000 --- a/examples/nexys_a7/single_lut_ram/src/tx_uart.v +++ /dev/null @@ -1,180 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Filename: txuart.v -// -// Project: Verilog Tutorial Example file -// -// Purpose: Transmit outputs over a single UART line. This particular UART -// implementation has been extremely simplified: it does not handle -// generating break conditions, nor does it handle anything other than the -// 8N1 (8 data bits, no parity, 1 stop bit) UART sub-protocol. -// -// To interface with this module, connect it to your system clock, and -// pass it the byte of data you wish to transmit. Strobe the i_wr line -// high for one cycle, and your data will be off. Wait until the 'o_busy' -// line is low before strobing the i_wr line again--this implementation -// has NO BUFFER, so strobing i_wr while the core is busy will just -// get ignored. The output will be placed on the o_txuart output line. -// -// There are known deficiencies in the formal proof found within this -// module. These have been left behind for you (the student) to fix. -// -// 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 tx_uart( - input wire i_clk, - input wire i_wr, - input wire [7:0] i_data, - output reg o_uart_tx, - output reg o_busy); - - parameter [23:0] CLOCKS_PER_BAUD = 24'd868; - - // A line to tell others when we are ready to accept data. If - // (i_wr)&&(!o_busy) is ever true, then the core has accepted a byte - // for transmission. - - // Define several states - localparam [3:0] START = 4'h0, - BIT_ZERO = 4'h1, - BIT_ONE = 4'h2, - BIT_TWO = 4'h3, - BIT_THREE = 4'h4, - BIT_FOUR = 4'h5, - BIT_FIVE = 4'h6, - BIT_SIX = 4'h7, - BIT_SEVEN = 4'h8, - LAST = 4'h8, - IDLE = 4'hf; - - reg [23:0] counter; - reg [3:0] state; - reg [8:0] lcl_data; - reg baud_stb; - - // o_busy - // - // This is a register, designed to be true is we are ever busy above. - // originally, this was going to be true if we were ever not in the - // idle state. The logic has since become more complex, hence we have - // a register dedicated to this and just copy out that registers value. - - initial o_busy = 1'b0; - initial state = IDLE; - always @(posedge i_clk) - if ((i_wr)&&(!o_busy)) - // Immediately start us off with a start bit - { o_busy, state } <= { 1'b1, START }; - else if (baud_stb) - begin - if (state == IDLE) // Stay in IDLE - { o_busy, state } <= { 1'b0, IDLE }; - else if (state < LAST) begin - o_busy <= 1'b1; - state <= state + 1'b1; - end else // Wait for IDLE - { o_busy, state } <= { 1'b1, IDLE }; - end - - - - // lcl_data - // - // This is our working copy of the i_data register which we use - // when transmitting. It is only of interest during transmit, and is - // allowed to be whatever at any other time. Hence, if o_busy isn't - // true, we can always set it. On the one clock where o_busy isn't - // true and i_wr is, we set it and o_busy is true thereafter. - // Then, on any baud_stb (i.e. change between baud intervals) - // we simple logically shift the register right to grab the next bit. - initial lcl_data = 9'h1ff; - always @(posedge i_clk) - if ((i_wr)&&(!o_busy)) - lcl_data <= { i_data, 1'b0 }; - else if (baud_stb) - lcl_data <= { 1'b1, lcl_data[8:1] }; - - // o_uart_tx - // - // This is the final result/output desired of this core. It's all - // centered about o_uart_tx. This is what finally needs to follow - // the UART protocol. - // - assign o_uart_tx = lcl_data[0]; - - - // All of the above logic is driven by the baud counter. Bits must last - // CLOCKS_PER_BAUD in length, and this baud counter is what we use to - // make certain of that. - // - // The basic logic is this: at the beginning of a bit interval, start - // the baud counter and set it to count CLOCKS_PER_BAUD. When it gets - // to zero, restart it. - // - // However, comparing a 28'bit number to zero can be rather complex-- - // especially if we wish to do anything else on that same clock. For - // that reason, we create "baud_stb". baud_stb is - // nothing more than a flag that is true anytime baud_counter is zero. - // It's true when the logic (above) needs to step to the next bit. - // Simple enough? - // - // I wish we could stop there, but there are some other (ugly) - // conditions to deal with that offer exceptions to this basic logic. - // - // 1. When the user has commanded a BREAK across the line, we need to - // wait several baud intervals following the break before we start - // transmitting, to give any receiver a chance to recognize that we are - // out of the break condition, and to know that the next bit will be - // a stop bit. - // - // 2. A reset is similar to a break condition--on both we wait several - // baud intervals before allowing a start bit. - // - // 3. In the idle state, we stop our counter--so that upon a request - // to transmit when idle we can start transmitting immediately, rather - // than waiting for the end of the next (fictitious and arbitrary) baud - // interval. - // - // When (i_wr)&&(!o_busy)&&(state == IDLE) then we're not only in - // the idle state, but we also just accepted a command to start writing - // the next word. At this point, the baud counter needs to be reset - // to the number of CLOCKS_PER_BAUD, and baud_stb set to zero. - // - // The logic is a bit twisted here, in that it will only check for the - // above condition when baud_stb is false--so as to make - // certain the STOP bit is complete. - initial baud_stb = 1'b1; - initial counter = 0; - always @(posedge i_clk) - if ((i_wr)&&(!o_busy)) - begin - counter <= CLOCKS_PER_BAUD - 1'b1; - baud_stb <= 1'b0; - end else if (!baud_stb) - begin - baud_stb <= (counter == 24'h01); - counter <= counter - 1'b1; - end else if (state != IDLE) - begin - counter <= CLOCKS_PER_BAUD - 1'b1; - baud_stb <= 1'b0; - end -endmodule diff --git a/examples/nexys_a7/single_lut_ram/src/uart_tx.v b/examples/nexys_a7/single_lut_ram/src/uart_tx.v deleted file mode 100644 index 920e98c..0000000 --- a/examples/nexys_a7/single_lut_ram/src/uart_tx.v +++ /dev/null @@ -1,75 +0,0 @@ -`default_nettype none -`timescale 1ns / 1ps - -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