aboutsummaryrefslogtreecommitdiffstats
path: root/fpga/usrp3/lib/control/cvita_uart.v
diff options
context:
space:
mode:
authorBen Hilburn <ben.hilburn@ettus.com>2013-10-10 10:17:27 -0700
committerBen Hilburn <ben.hilburn@ettus.com>2013-10-10 10:17:27 -0700
commit0df4b801a34697f2058b4a7b95e08d2a0576c9db (patch)
treebe10e78d1a97c037a9e7492360a178d1873b9c09 /fpga/usrp3/lib/control/cvita_uart.v
parent6e7bc850b66e8188718248b76b729c7cf9c89700 (diff)
downloaduhd-0df4b801a34697f2058b4a7b95e08d2a0576c9db.tar.gz
uhd-0df4b801a34697f2058b4a7b95e08d2a0576c9db.tar.bz2
uhd-0df4b801a34697f2058b4a7b95e08d2a0576c9db.zip
Squashed B200 FPGA Source. Code from Josh Blum, Ian Buckley, and Matt Ettus.
Diffstat (limited to 'fpga/usrp3/lib/control/cvita_uart.v')
-rw-r--r--fpga/usrp3/lib/control/cvita_uart.v164
1 files changed, 164 insertions, 0 deletions
diff --git a/fpga/usrp3/lib/control/cvita_uart.v b/fpga/usrp3/lib/control/cvita_uart.v
new file mode 100644
index 000000000..cbb272fc2
--- /dev/null
+++ b/fpga/usrp3/lib/control/cvita_uart.v
@@ -0,0 +1,164 @@
+
+//
+// Copyright 2013 Ettus Research LLC
+//
+
+
+//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),
+ .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