diff options
author | Ben Hilburn <ben.hilburn@ettus.com> | 2013-10-10 10:17:27 -0700 |
---|---|---|
committer | Ben Hilburn <ben.hilburn@ettus.com> | 2013-10-10 10:17:27 -0700 |
commit | 0df4b801a34697f2058b4a7b95e08d2a0576c9db (patch) | |
tree | be10e78d1a97c037a9e7492360a178d1873b9c09 /fpga/usrp3/lib/control/cvita_uart.v | |
parent | 6e7bc850b66e8188718248b76b729c7cf9c89700 (diff) | |
download | uhd-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.v | 164 |
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 |