aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/control_200/cvita_uart.v
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/usrp3/lib/control_200/cvita_uart.v')
-rw-r--r--fpga/usrp3/lib/control_200/cvita_uart.v167
1 files changed, 167 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/control_200/cvita_uart.v b/fpga/usrp3/lib/control_200/cvita_uart.v
new file mode 100644
index 000000000..1afcbb5f0
--- /dev/null
+++ b/fpga/usrp3/lib/control_200/cvita_uart.v
@@ -0,0 +1,167 @@
+
+//
+// Copyright 2013 Ettus Research LLC
+// Copyright 2018 Ettus Research, a National Instruments Company
+//
+// SPDX-License-Identifier: LGPL-3.0-or-later
+//
+
+
+//create a compressed vita based uart data interface
+
+module cvita_uart
+#(
+ parameter SIZE = 0
+)
+(
+ //clocking interface
+ input clk, input rst,
+
+ //uart interface
+ input rxd, output txd,
+
+ //chdr fifo input
+ input [63:0] i_tdata,
+ input i_tlast,
+ input i_tvalid,
+ output i_tready,
+
+ //chdr fifo output
+ output [63:0] o_tdata,
+ output o_tlast,
+ output o_tvalid,
+ input o_tready
+);
+
+ reg [31:0] sid;
+
+ //baud clock divider
+ reg [15:0] clkdiv;
+
+ //hold rx in disable until a tx event
+ reg rxd_enable;
+
+ //==================================================================
+ //== RXD capture and packet generation interface
+ //==================================================================
+ wire [7:0] rx_char;
+ wire fifo_empty;
+ wire fifo_read;
+ reg [11:0] seqnum;
+ wire pgen_trigger;
+ wire pgen_done;
+
+ //rx uart capture
+ simple_uart_rx #(.SIZE(SIZE)) simple_uart_rx
+ (
+ .clk(clk), .rst(rst | ~rxd_enable),
+ .fifo_out(rx_char), .fifo_read(fifo_read), .fifo_level(), .fifo_empty(fifo_empty),
+ .clkdiv(clkdiv), .rx(rxd)
+ );
+
+ //packet generation - holds rx character
+ context_packet_gen context_packet_gen
+ (
+ .clk(clk), .reset(rst), .clear(1'b0),
+ .trigger(pgen_trigger),
+ .seqnum(seqnum),
+ .sid({sid[15:0], sid[31:16]}),
+ .body({56'b0, rx_char}),
+ .vita_time(64'b0),
+
+ .done(pgen_done),
+ .o_tdata(o_tdata), .o_tlast(o_tlast), .o_tvalid(o_tvalid), .o_tready(o_tready)
+ );
+
+ //state machine to manage pgen and rx uart
+ reg [1:0] rxd_state;
+ localparam RXD_STATE_RECV_CHAR = 0;
+ localparam RXD_STATE_PGEN_TRIG = 1;
+ localparam RXD_STATE_WAIT_DONE = 2;
+ localparam RXD_STATE_READ_FIFO = 3;
+
+ always @(posedge clk) begin
+ if (rst) begin
+ seqnum <= 12'b0;
+ rxd_state <= RXD_STATE_RECV_CHAR;
+ end
+ else case (rxd_state)
+
+ RXD_STATE_RECV_CHAR: begin
+ if (!fifo_empty && rxd_enable) rxd_state <= RXD_STATE_PGEN_TRIG;
+ end
+
+ RXD_STATE_PGEN_TRIG: begin
+ rxd_state <= RXD_STATE_WAIT_DONE;
+ end
+
+ RXD_STATE_WAIT_DONE: begin
+ if (pgen_done) rxd_state <= RXD_STATE_READ_FIFO;
+ end
+
+ RXD_STATE_READ_FIFO: begin
+ rxd_state <= RXD_STATE_RECV_CHAR;
+ seqnum <= seqnum + 1'b1;
+ end
+
+ endcase //rxd_state
+ end
+
+ assign fifo_read = (rxd_state == RXD_STATE_READ_FIFO) || (!rxd_enable);
+ assign pgen_trigger = (rxd_state == RXD_STATE_PGEN_TRIG);
+
+ //==================================================================
+ //== TXD generation and packet control interface
+ //==================================================================
+ wire [7:0] tx_char;
+ wire fifo_write;
+ wire fifo_full;
+
+ simple_uart_tx #(.SIZE(SIZE)) simple_uart_tx
+ (
+ .clk(clk), .rst(rst),
+ .fifo_in(tx_char), .fifo_write(fifo_write), .fifo_level(), .fifo_full(fifo_full),
+ .clkdiv(clkdiv), .baudclk(), .tx(txd)
+ );
+
+ //state machine to manage control and tx uart
+ reg [1:0] txd_state;
+ localparam TXD_STATE_RECV_CHDR = 0;
+ localparam TXD_STATE_RECV_TIME = 1;
+ localparam TXD_STATE_RECV_BODY = 2;
+ localparam TXD_STATE_DROP_FIFO = 3;
+
+ always @(posedge clk) begin
+ if (rst) begin;
+ txd_state <= TXD_STATE_RECV_CHDR;
+ rxd_enable <= 1'b0;
+ end
+ if (i_tvalid && i_tready) case (txd_state)
+
+ TXD_STATE_RECV_CHDR: begin
+ txd_state <= (i_tdata[61])? TXD_STATE_RECV_TIME : TXD_STATE_RECV_BODY;
+ sid <= i_tdata[31:0];
+ end
+
+ TXD_STATE_RECV_TIME: begin
+ txd_state <= TXD_STATE_RECV_BODY;
+ end
+
+ TXD_STATE_RECV_BODY: begin
+ txd_state <= (i_tlast)? TXD_STATE_RECV_CHDR : TXD_STATE_DROP_FIFO;
+ clkdiv <= i_tdata[47:32];
+ rxd_enable <= 1'b1;
+ end
+
+ TXD_STATE_DROP_FIFO: begin
+ if (i_tlast) txd_state <= TXD_STATE_RECV_CHDR;
+ end
+
+ endcase //txd_state
+ end
+
+ assign tx_char = i_tdata[7:0];
+ assign fifo_write = (txd_state == TXD_STATE_RECV_BODY) && i_tvalid && i_tready;
+ assign i_tready = !fifo_full;
+
+endmodule // cvita_uart