1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 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
|