mirror of
https://github.com/fpganinja/taxi.git
synced 2025-12-09 17:08:38 -08:00
lss: Implement fractional baud rate generation for UART
Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
@@ -78,7 +78,7 @@ for (genvar n = 0; n < UART_CNT; n = n + 1) begin : uart_ch
|
|||||||
taxi_axis_if #(.DATA_W(8)) axis_uart();
|
taxi_axis_if #(.DATA_W(8)) axis_uart();
|
||||||
|
|
||||||
taxi_uart
|
taxi_uart
|
||||||
uut (
|
uart_inst (
|
||||||
.clk(clk_125mhz),
|
.clk(clk_125mhz),
|
||||||
.rst(rst_125mhz),
|
.rst(rst_125mhz),
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ for (genvar n = 0; n < UART_CNT; n = n + 1) begin : uart_ch
|
|||||||
/*
|
/*
|
||||||
* Configuration
|
* Configuration
|
||||||
*/
|
*/
|
||||||
.prescale(16'(125000000/115200/8))
|
.prescale(16'(125000000/115200))
|
||||||
);
|
);
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ assign phy_reset_n = !rst;
|
|||||||
taxi_axis_if #(.DATA_W(8)) axis_uart();
|
taxi_axis_if #(.DATA_W(8)) axis_uart();
|
||||||
|
|
||||||
taxi_uart
|
taxi_uart
|
||||||
uut (
|
uart_inst (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst(rst),
|
.rst(rst),
|
||||||
|
|
||||||
@@ -112,7 +112,7 @@ uut (
|
|||||||
/*
|
/*
|
||||||
* Configuration
|
* Configuration
|
||||||
*/
|
*/
|
||||||
.prescale(16'(125000000/115200/8))
|
.prescale(16'(125000000/115200))
|
||||||
);
|
);
|
||||||
|
|
||||||
taxi_axis_if #(.DATA_W(8), .ID_W(8)) axis_eth();
|
taxi_axis_if #(.DATA_W(8), .ID_W(8)) axis_eth();
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ assign uart_rst_n = 1'b1;
|
|||||||
taxi_axis_if #(.DATA_W(8)) axis_uart();
|
taxi_axis_if #(.DATA_W(8)) axis_uart();
|
||||||
|
|
||||||
taxi_uart
|
taxi_uart
|
||||||
uut (
|
uart_inst (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst(rst),
|
.rst(rst),
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ uut (
|
|||||||
/*
|
/*
|
||||||
* Configuration
|
* Configuration
|
||||||
*/
|
*/
|
||||||
.prescale(16'(125000000/115200/8))
|
.prescale(16'(125000000/115200))
|
||||||
);
|
);
|
||||||
|
|
||||||
// BASE-T PHY
|
// BASE-T PHY
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ assign uart_rts = 0;
|
|||||||
taxi_axis_if #(.DATA_W(8)) axis_uart();
|
taxi_axis_if #(.DATA_W(8)) axis_uart();
|
||||||
|
|
||||||
taxi_uart
|
taxi_uart
|
||||||
uut (
|
uart_inst (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst(rst),
|
.rst(rst),
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ uut (
|
|||||||
/*
|
/*
|
||||||
* Configuration
|
* Configuration
|
||||||
*/
|
*/
|
||||||
.prescale(16'(125000000/115200/8))
|
.prescale(16'(125000000/115200))
|
||||||
);
|
);
|
||||||
|
|
||||||
// BASE-T PHY
|
// BASE-T PHY
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ assign uart_rts = 0;
|
|||||||
taxi_axis_if #(.DATA_W(8)) axis_uart();
|
taxi_axis_if #(.DATA_W(8)) axis_uart();
|
||||||
|
|
||||||
taxi_uart
|
taxi_uart
|
||||||
uut (
|
uart_inst (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst(rst),
|
.rst(rst),
|
||||||
|
|
||||||
@@ -140,7 +140,7 @@ uut (
|
|||||||
/*
|
/*
|
||||||
* Configuration
|
* Configuration
|
||||||
*/
|
*/
|
||||||
.prescale(16'(125000000/115200/8))
|
.prescale(16'(125000000/115200))
|
||||||
);
|
);
|
||||||
|
|
||||||
// BASE-T PHY
|
// BASE-T PHY
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ assign uart_rts = 0;
|
|||||||
taxi_axis_if #(.DATA_W(8)) axis_uart();
|
taxi_axis_if #(.DATA_W(8)) axis_uart();
|
||||||
|
|
||||||
taxi_uart
|
taxi_uart
|
||||||
uut (
|
uart_inst (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst(rst),
|
.rst(rst),
|
||||||
|
|
||||||
@@ -122,7 +122,7 @@ uut (
|
|||||||
/*
|
/*
|
||||||
* Configuration
|
* Configuration
|
||||||
*/
|
*/
|
||||||
.prescale(16'(125000000/115200/8))
|
.prescale(16'(125000000/115200))
|
||||||
);
|
);
|
||||||
|
|
||||||
// BASE-T PHY
|
// BASE-T PHY
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ assign uart_rts = 0;
|
|||||||
taxi_axis_if #(.DATA_W(8)) axis_uart();
|
taxi_axis_if #(.DATA_W(8)) axis_uart();
|
||||||
|
|
||||||
taxi_uart
|
taxi_uart
|
||||||
uut (
|
uart_inst (
|
||||||
.clk(clk_125mhz),
|
.clk(clk_125mhz),
|
||||||
.rst(rst_125mhz),
|
.rst(rst_125mhz),
|
||||||
|
|
||||||
@@ -142,7 +142,7 @@ uut (
|
|||||||
/*
|
/*
|
||||||
* Configuration
|
* Configuration
|
||||||
*/
|
*/
|
||||||
.prescale(16'(125000000/115200/8))
|
.prescale(16'(125000000/115200))
|
||||||
);
|
);
|
||||||
|
|
||||||
// BASE-T PHY
|
// BASE-T PHY
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ assign uart_cts = 0;
|
|||||||
taxi_axis_if #(.DATA_W(8)) axis_uart();
|
taxi_axis_if #(.DATA_W(8)) axis_uart();
|
||||||
|
|
||||||
taxi_uart
|
taxi_uart
|
||||||
uut (
|
uart_inst (
|
||||||
.clk(clk_125mhz),
|
.clk(clk_125mhz),
|
||||||
.rst(rst_125mhz),
|
.rst(rst_125mhz),
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ uut (
|
|||||||
/*
|
/*
|
||||||
* Configuration
|
* Configuration
|
||||||
*/
|
*/
|
||||||
.prescale(16'(125000000/115200/8))
|
.prescale(16'(125000000/115200))
|
||||||
);
|
);
|
||||||
|
|
||||||
// SFP+
|
// SFP+
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ assign uart_cts = 0;
|
|||||||
taxi_axis_if #(.DATA_W(8)) axis_uart();
|
taxi_axis_if #(.DATA_W(8)) axis_uart();
|
||||||
|
|
||||||
taxi_uart
|
taxi_uart
|
||||||
uut (
|
uart_inst (
|
||||||
.clk(clk_125mhz),
|
.clk(clk_125mhz),
|
||||||
.rst(rst_125mhz),
|
.rst(rst_125mhz),
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ uut (
|
|||||||
/*
|
/*
|
||||||
* Configuration
|
* Configuration
|
||||||
*/
|
*/
|
||||||
.prescale(16'(125000000/115200/8))
|
.prescale(16'(125000000/115200))
|
||||||
);
|
);
|
||||||
|
|
||||||
// SFP+
|
// SFP+
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ assign uart_cts = 0;
|
|||||||
taxi_axis_if #(.DATA_W(8)) axis_uart();
|
taxi_axis_if #(.DATA_W(8)) axis_uart();
|
||||||
|
|
||||||
taxi_uart
|
taxi_uart
|
||||||
uut (
|
uart_inst (
|
||||||
.clk(clk_125mhz),
|
.clk(clk_125mhz),
|
||||||
.rst(rst_125mhz),
|
.rst(rst_125mhz),
|
||||||
|
|
||||||
@@ -103,7 +103,7 @@ uut (
|
|||||||
/*
|
/*
|
||||||
* Configuration
|
* Configuration
|
||||||
*/
|
*/
|
||||||
.prescale(16'(125000000/115200/8))
|
.prescale(16'(125000000/115200))
|
||||||
);
|
);
|
||||||
|
|
||||||
// SFP+
|
// SFP+
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ Authors:
|
|||||||
/*
|
/*
|
||||||
* AXI4-Stream UART
|
* AXI4-Stream UART
|
||||||
*/
|
*/
|
||||||
module taxi_uart
|
module taxi_uart #(
|
||||||
|
parameter PRE_W = 16
|
||||||
|
)
|
||||||
(
|
(
|
||||||
input wire logic clk,
|
input wire logic clk,
|
||||||
input wire logic rst,
|
input wire logic rst,
|
||||||
@@ -47,13 +49,15 @@ module taxi_uart
|
|||||||
/*
|
/*
|
||||||
* Configuration
|
* Configuration
|
||||||
*/
|
*/
|
||||||
input wire logic [15:0] prescale
|
input wire logic [PRE_W-1:0] prescale
|
||||||
|
|
||||||
);
|
);
|
||||||
|
|
||||||
wire baud_clk;
|
wire baud_clk;
|
||||||
|
|
||||||
taxi_uart_brg
|
taxi_uart_brg #(
|
||||||
|
.PRE_W(PRE_W)
|
||||||
|
)
|
||||||
uart_brg_inst (
|
uart_brg_inst (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst(rst),
|
.rst(rst),
|
||||||
|
|||||||
@@ -15,7 +15,9 @@ Authors:
|
|||||||
/*
|
/*
|
||||||
* AXI4-Stream UART baud rate generator
|
* AXI4-Stream UART baud rate generator
|
||||||
*/
|
*/
|
||||||
module taxi_uart_brg
|
module taxi_uart_brg #(
|
||||||
|
parameter PRE_W = 16
|
||||||
|
)
|
||||||
(
|
(
|
||||||
input wire logic clk,
|
input wire logic clk,
|
||||||
input wire logic rst,
|
input wire logic rst,
|
||||||
@@ -28,26 +30,37 @@ module taxi_uart_brg
|
|||||||
/*
|
/*
|
||||||
* Configuration
|
* Configuration
|
||||||
*/
|
*/
|
||||||
input wire logic [15:0] prescale
|
input wire logic [PRE_W-1:0] prescale
|
||||||
);
|
);
|
||||||
|
|
||||||
logic [15:0] prescale_reg = 0;
|
localparam FRAC_W = 3;
|
||||||
|
localparam INT_W = PRE_W - FRAC_W;
|
||||||
|
|
||||||
|
logic [INT_W-1:0] prescale_int_reg = 0;
|
||||||
|
logic [FRAC_W-1:0] prescale_frac_reg = 0;
|
||||||
|
logic frac_ovf_reg = 1'b0;
|
||||||
logic baud_clk_reg = 1'b0;
|
logic baud_clk_reg = 1'b0;
|
||||||
|
|
||||||
assign baud_clk = baud_clk_reg;
|
assign baud_clk = baud_clk_reg;
|
||||||
|
|
||||||
always_ff @(posedge clk) begin
|
always_ff @(posedge clk) begin
|
||||||
|
frac_ovf_reg <= 1'b0;
|
||||||
baud_clk_reg <= 1'b0;
|
baud_clk_reg <= 1'b0;
|
||||||
|
|
||||||
if (prescale_reg != 0) begin
|
if (frac_ovf_reg) begin
|
||||||
prescale_reg <= prescale_reg - 1;
|
// delay extra cycle
|
||||||
|
frac_ovf_reg <= 1'b0;
|
||||||
|
end else if (prescale_int_reg != 0) begin
|
||||||
|
prescale_int_reg <= prescale_int_reg - 1;
|
||||||
end else begin
|
end else begin
|
||||||
prescale_reg <= prescale - 1;
|
prescale_int_reg <= prescale[FRAC_W +: INT_W] - 1;
|
||||||
|
{frac_ovf_reg, prescale_frac_reg} <= prescale_frac_reg + prescale[FRAC_W-1:0];
|
||||||
baud_clk_reg <= 1'b1;
|
baud_clk_reg <= 1'b1;
|
||||||
end
|
end
|
||||||
|
|
||||||
if (rst) begin
|
if (rst) begin
|
||||||
prescale_reg <= 0;
|
prescale_int_reg <= 0;
|
||||||
|
prescale_frac_reg <= 0;
|
||||||
baud_clk_reg <= 0;
|
baud_clk_reg <= 0;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ Authors:
|
|||||||
* XFCP Interface (UART)
|
* XFCP Interface (UART)
|
||||||
*/
|
*/
|
||||||
module taxi_xfcp_if_uart #(
|
module taxi_xfcp_if_uart #(
|
||||||
|
parameter PRE_W = 16,
|
||||||
parameter TX_FIFO_DEPTH = 512,
|
parameter TX_FIFO_DEPTH = 512,
|
||||||
parameter RX_FIFO_DEPTH = 512
|
parameter RX_FIFO_DEPTH = 512
|
||||||
)
|
)
|
||||||
@@ -38,13 +39,15 @@ module taxi_xfcp_if_uart #(
|
|||||||
/*
|
/*
|
||||||
* Configuration
|
* Configuration
|
||||||
*/
|
*/
|
||||||
input wire logic [15:0] prescale
|
input wire logic [PRE_W-1:0] prescale
|
||||||
);
|
);
|
||||||
|
|
||||||
taxi_axis_if #(.DATA_W(8), .LAST_EN(0)) uart_tx(), uart_rx();
|
taxi_axis_if #(.DATA_W(8), .LAST_EN(0)) uart_tx(), uart_rx();
|
||||||
taxi_axis_if #(.DATA_W(8), .LAST_EN(1), .USER_EN(1), .USER_W(1)) fifo_tx(), fifo_rx();
|
taxi_axis_if #(.DATA_W(8), .LAST_EN(1), .USER_EN(1), .USER_W(1)) fifo_tx(), fifo_rx();
|
||||||
|
|
||||||
taxi_uart
|
taxi_uart #(
|
||||||
|
.PRE_W(PRE_W)
|
||||||
|
)
|
||||||
uart_inst (
|
uart_inst (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst(rst),
|
.rst(rst),
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ uniq_base = $(if $1,$(call uniq_base,$(foreach f,$1,$(if $(filter-out $(notdir $
|
|||||||
VERILOG_SOURCES := $(call uniq_base,$(call process_f_files,$(VERILOG_SOURCES)))
|
VERILOG_SOURCES := $(call uniq_base,$(call process_f_files,$(VERILOG_SOURCES)))
|
||||||
|
|
||||||
# module parameters
|
# module parameters
|
||||||
export PARAM_DATA_W ?= 8
|
export PARAM_PRE_W := 16
|
||||||
|
export PARAM_DATA_W := 8
|
||||||
|
|
||||||
ifeq ($(SIM), icarus)
|
ifeq ($(SIM), icarus)
|
||||||
PLUSARGS += -fst
|
PLUSARGS += -fst
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ class TB:
|
|||||||
self.axis_source = AxiStreamSource(AxiStreamBus.from_entity(dut.s_axis_tx), dut.clk, dut.rst)
|
self.axis_source = AxiStreamSource(AxiStreamBus.from_entity(dut.s_axis_tx), dut.clk, dut.rst)
|
||||||
self.axis_sink = AxiStreamSink(AxiStreamBus.from_entity(dut.m_axis_rx), dut.clk, dut.rst)
|
self.axis_sink = AxiStreamSink(AxiStreamBus.from_entity(dut.m_axis_rx), dut.clk, dut.rst)
|
||||||
|
|
||||||
dut.prescale.setimmediatevalue(int(1/8e-9/baud/8))
|
dut.prescale.setimmediatevalue(int(1/8e-9/baud))
|
||||||
|
|
||||||
async def reset(self):
|
async def reset(self):
|
||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
@@ -168,6 +168,7 @@ def test_taxi_uart(request):
|
|||||||
|
|
||||||
parameters = {}
|
parameters = {}
|
||||||
|
|
||||||
|
parameters['PRE_W'] = 16
|
||||||
parameters['DATA_W'] = 8
|
parameters['DATA_W'] = 8
|
||||||
|
|
||||||
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
|
extra_env = {f'PARAM_{k}': str(v) for k, v in parameters.items()}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ Authors:
|
|||||||
module test_taxi_uart #
|
module test_taxi_uart #
|
||||||
(
|
(
|
||||||
/* verilator lint_off WIDTHTRUNC */
|
/* verilator lint_off WIDTHTRUNC */
|
||||||
|
parameter PRE_W = 16,
|
||||||
parameter DATA_W = 8
|
parameter DATA_W = 8
|
||||||
/* verilator lint_on WIDTHTRUNC */
|
/* verilator lint_on WIDTHTRUNC */
|
||||||
)
|
)
|
||||||
@@ -37,9 +38,11 @@ logic rx_busy;
|
|||||||
logic rx_overrun_error;
|
logic rx_overrun_error;
|
||||||
logic rx_frame_error;
|
logic rx_frame_error;
|
||||||
|
|
||||||
logic [15:0] prescale;
|
logic [PRE_W-1:0] prescale;
|
||||||
|
|
||||||
taxi_uart
|
taxi_uart #(
|
||||||
|
.PRE_W(PRE_W)
|
||||||
|
)
|
||||||
uut (
|
uut (
|
||||||
.clk(clk),
|
.clk(clk),
|
||||||
.rst(rst),
|
.rst(rst),
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ uniq_base = $(if $1,$(call uniq_base,$(foreach f,$1,$(if $(filter-out $(notdir $
|
|||||||
VERILOG_SOURCES := $(call uniq_base,$(call process_f_files,$(VERILOG_SOURCES)))
|
VERILOG_SOURCES := $(call uniq_base,$(call process_f_files,$(VERILOG_SOURCES)))
|
||||||
|
|
||||||
# module parameters
|
# module parameters
|
||||||
|
export PARAM_PRE_W := 16
|
||||||
export PARAM_TX_FIFO_DEPTH := 512
|
export PARAM_TX_FIFO_DEPTH := 512
|
||||||
export PARAM_RX_FIFO_DEPTH := 512
|
export PARAM_RX_FIFO_DEPTH := 512
|
||||||
|
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ class TB(object):
|
|||||||
self.dsp_source = AxiStreamSource(AxiStreamBus.from_entity(dut.xfcp_dsp_us), dut.clk, dut.rst)
|
self.dsp_source = AxiStreamSource(AxiStreamBus.from_entity(dut.xfcp_dsp_us), dut.clk, dut.rst)
|
||||||
self.dsp_sink = AxiStreamSink(AxiStreamBus.from_entity(dut.xfcp_dsp_ds), dut.clk, dut.rst)
|
self.dsp_sink = AxiStreamSink(AxiStreamBus.from_entity(dut.xfcp_dsp_ds), dut.clk, dut.rst)
|
||||||
|
|
||||||
dut.prescale.setimmediatevalue(int(1/8e-9/baud/8))
|
dut.prescale.setimmediatevalue(int(1/8e-9/baud))
|
||||||
|
|
||||||
async def reset(self):
|
async def reset(self):
|
||||||
self.dut.rst.setimmediatevalue(0)
|
self.dut.rst.setimmediatevalue(0)
|
||||||
@@ -181,6 +181,7 @@ def test_taxi_xfcp_if_uart(request):
|
|||||||
|
|
||||||
parameters = {}
|
parameters = {}
|
||||||
|
|
||||||
|
parameters['PRE_W'] = 16
|
||||||
parameters['TX_FIFO_DEPTH'] = 512
|
parameters['TX_FIFO_DEPTH'] = 512
|
||||||
parameters['RX_FIFO_DEPTH'] = 512
|
parameters['RX_FIFO_DEPTH'] = 512
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ Authors:
|
|||||||
module test_taxi_xfcp_if_uart #
|
module test_taxi_xfcp_if_uart #
|
||||||
(
|
(
|
||||||
/* verilator lint_off WIDTHTRUNC */
|
/* verilator lint_off WIDTHTRUNC */
|
||||||
|
parameter PRE_W = 16,
|
||||||
parameter TX_FIFO_DEPTH = 512,
|
parameter TX_FIFO_DEPTH = 512,
|
||||||
parameter RX_FIFO_DEPTH = 512
|
parameter RX_FIFO_DEPTH = 512
|
||||||
/* verilator lint_on WIDTHTRUNC */
|
/* verilator lint_on WIDTHTRUNC */
|
||||||
@@ -32,9 +33,10 @@ logic uart_txd;
|
|||||||
|
|
||||||
taxi_axis_if #(.DATA_W(8), .LAST_EN(1), .USER_EN(1), .USER_W(1)) xfcp_dsp_ds(), xfcp_dsp_us();
|
taxi_axis_if #(.DATA_W(8), .LAST_EN(1), .USER_EN(1), .USER_W(1)) xfcp_dsp_ds(), xfcp_dsp_us();
|
||||||
|
|
||||||
logic [15:0] prescale;
|
logic [PRE_W-1:0] prescale;
|
||||||
|
|
||||||
taxi_xfcp_if_uart #(
|
taxi_xfcp_if_uart #(
|
||||||
|
.PRE_W(PRE_W),
|
||||||
.TX_FIFO_DEPTH(TX_FIFO_DEPTH),
|
.TX_FIFO_DEPTH(TX_FIFO_DEPTH),
|
||||||
.RX_FIFO_DEPTH(RX_FIFO_DEPTH)
|
.RX_FIFO_DEPTH(RX_FIFO_DEPTH)
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user