From ecd5ba6dd9084ca101c695b98d89af3b97f0147f Mon Sep 17 00:00:00 2001 From: maksyuki Date: Thu, 4 Jan 2024 21:18:30 +0800 Subject: [PATCH] feat: use reg with en signal to rewrite module --- rtl/apb4_uart.sv | 102 +++++++++++++++++++++++++++------------------ rtl/uart_define.sv | 16 +++---- rtl/uart_rx.sv | 8 +++- rtl/uart_tx.sv | 11 ++++- 4 files changed, 86 insertions(+), 51 deletions(-) diff --git a/rtl/apb4_uart.sv b/rtl/apb4_uart.sv index f1c98b5..57bdab0 100644 --- a/rtl/apb4_uart.sv +++ b/rtl/apb4_uart.sv @@ -25,7 +25,6 @@ `include "uart_define.sv" module apb4_uart #( - // parameter int FIFO_DEPTH = 16, parameter int FIFO_DEPTH = 64, parameter int LOG_FIFO_DEPTH = $clog2(FIFO_DEPTH) ) ( @@ -34,10 +33,16 @@ module apb4_uart #( ); logic [3:0] s_apb4_addr; + logic s_apb4_wr_hdshk, s_apb4_rd_hdshk; logic [`UART_LCR_WIDTH-1:0] s_uart_lcr_d, s_uart_lcr_q; + logic s_uart_lcr_en; logic [`UART_DIV_WIDTH-1:0] s_uart_div_d, s_uart_div_q; + logic s_uart_div_en; logic [`UART_FCR_WIDTH-1:0] s_uart_fcr_d, s_uart_fcr_q; + logic s_uart_fcr_en; logic [`UART_LSR_WIDTH-1:0] s_uart_lsr_d, s_uart_lsr_q; + logic s_bit_stb, s_bit_pen, s_bit_rf_clr, s_bit_tf_clr; + logic [1:0] s_bit_wls, s_bit_ps, s_bit_rx_trg_levl; logic s_clr_int, s_parity_err; logic s_tx_push_valid, s_tx_push_ready, s_tx_pop_valid, s_tx_pop_ready; logic s_rx_pop_valid, s_rx_pop_ready; @@ -46,24 +51,37 @@ module apb4_uart #( logic [8:0] s_rx_pop_data; logic [LOG_FIFO_DEPTH:0] s_tx_elem, s_rx_elem; - assign s_apb4_addr = apb4.paddr[5:2]; - assign s_apb4_wr_hdshk = apb4.psel && apb4.penable && apb4.pwrite; - assign s_apb4_rd_hdshk = apb4.psel && apb4.penable && (~apb4.pwrite); - assign apb4.pready = 1'b1; - assign apb4.pslverr = 1'b0; + assign s_apb4_addr = apb4.paddr[5:2]; + assign s_apb4_wr_hdshk = apb4.psel && apb4.penable && apb4.pwrite; + assign s_apb4_rd_hdshk = apb4.psel && apb4.penable && (~apb4.pwrite); + assign apb4.pready = 1'b1; + assign apb4.pslverr = 1'b0; - assign s_uart_lcr_d = (s_apb4_wr_hdshk && s_apb4_addr == `UART_LCR) ? apb4.pwdata[`UART_LCR_WIDTH-1:0] : s_uart_lcr_q; - dffr #(`UART_LCR_WIDTH) u_uart_lcr_dffr ( + assign s_bit_wls = s_uart_lcr_q[4:3]; + assign s_bit_stb = s_uart_lcr_q[5]; + assign s_bit_pen = s_uart_lcr_q[6]; + assign s_bit_ps = s_uart_lcr_q[8:7]; + + assign s_bit_rf_clr = s_uart_fcr_q[0]; + assign s_bit_tf_clr = s_uart_fcr_q[1]; + assign s_bit_rx_trg_levl = s_uart_fcr_q[3:2]; + + assign s_uart_lcr_en = s_apb4_wr_hdshk && s_apb4_addr == `UART_LCR; + assign s_uart_lcr_d = s_uart_lcr_en ? apb4.pwdata[`UART_LCR_WIDTH-1:0] : s_uart_lcr_q; + dffer #(`UART_LCR_WIDTH) u_uart_lcr_dffer ( apb4.pclk, apb4.presetn, + s_uart_lcr_en, s_uart_lcr_d, s_uart_lcr_q ); - assign s_uart_div_d = (s_apb4_wr_hdshk && s_apb4_addr == `UART_DIV) ? apb4.pwdata[`UART_DIV_WIDTH-1:0] : s_uart_div_q; - dffrc #(`UART_DIV_WIDTH, `UART_DIV_MIN_VAL) u_uart_div_dffrc ( + assign s_uart_div_en = s_apb4_wr_hdshk && s_apb4_addr == `UART_DIV; + assign s_uart_div_d = s_uart_div_en ? apb4.pwdata[`UART_DIV_WIDTH-1:0] : s_uart_div_q; + dfferc #(`UART_DIV_WIDTH, `UART_DIV_MIN_VAL) u_uart_div_dfferc ( apb4.pclk, apb4.presetn, + s_uart_div_en, s_uart_div_d, s_uart_div_q ); @@ -76,10 +94,12 @@ module apb4_uart #( end end - assign s_uart_fcr_d = (s_apb4_wr_hdshk && s_apb4_addr == `UART_FCR) ? apb4.pwdata[`UART_FCR_WIDTH-1:0] : s_uart_fcr_q; - dffr #(`UART_FCR_WIDTH) u_uart_fcr_dffr ( + assign s_uart_fcr_en = s_apb4_wr_hdshk && s_apb4_addr == `UART_FCR; + assign s_uart_fcr_d = s_uart_fcr_en ? apb4.pwdata[`UART_FCR_WIDTH-1:0] : s_uart_fcr_q; + dffer #(`UART_FCR_WIDTH) u_uart_fcr_dffer ( apb4.pclk, apb4.presetn, + s_uart_fcr_en, s_uart_fcr_d, s_uart_fcr_q ); @@ -125,7 +145,7 @@ module apb4_uart #( ) u_tx_fifo ( .clk_i (apb4.pclk), .rst_n_i(apb4.presetn), - .flush_i(s_uart_fcr_q[1]), + .flush_i(s_bit_tf_clr), .cnt_o (s_tx_elem), .push_i (s_tx_push_valid), .full_o (), @@ -136,18 +156,19 @@ module apb4_uart #( ); uart_tx u_uart_tx ( - .clk_i (apb4.pclk), - .rst_n_i (apb4.presetn), - .tx_o (uart.uart_tx_o), - .busy_o (), - .cfg_en_i (1'b1), - .cfg_div_i (s_uart_div_q[`UART_DIV_WIDTH-1:0]), - .cfg_parity_en_i(s_uart_lcr_q[6]), - .cfg_bits_i (s_uart_lcr_q[4:3]), - .cfg_stop_bits_i(s_uart_lcr_q[5]), - .tx_data_i (s_tx_pop_data), - .tx_valid_i (~s_tx_pop_valid), - .tx_ready_o (s_tx_pop_ready) + .clk_i (apb4.pclk), + .rst_n_i (apb4.presetn), + .tx_o (uart.uart_tx_o), + .busy_o (), + .cfg_en_i (1'b1), + .cfg_div_i (s_uart_div_q[`UART_DIV_WIDTH-1:0]), + .cfg_parity_en_i (s_bit_pen), + .cfg_parity_sel_i(s_bit_ps), + .cfg_bits_i (s_bit_wls), + .cfg_stop_bits_i (s_bit_stb), + .tx_data_i (s_tx_pop_data), + .tx_valid_i (~s_tx_pop_valid), + .tx_ready_o (s_tx_pop_ready) ); fifo #( @@ -156,7 +177,7 @@ module apb4_uart #( ) u_rx_fifo ( .clk_i (apb4.pclk), .rst_n_i(apb4.presetn), - .flush_i(s_uart_fcr_q[0]), + .flush_i(s_bit_rf_clr), .cnt_o (s_rx_elem), .push_i (s_rx_push_valid), .full_o (s_rx_push_ready), @@ -167,19 +188,20 @@ module apb4_uart #( ); uart_rx u_uart_rx ( - .clk_i (apb4.pclk), - .rst_n_i (apb4.presetn), - .rx_i (uart.uart_rx_i), - .busy_o (), - .cfg_en_i (1'b1), - .cfg_div_i (s_uart_div_q[`UART_DIV_WIDTH-1:0]), - .cfg_parity_en_i(s_uart_lcr_q[6]), - .cfg_bits_i (s_uart_lcr_q[4:3]), - .err_o (s_parity_err), - .err_clr_i (1'b1), - .rx_data_o (s_rx_push_data), - .rx_valid_o (s_rx_push_valid), - .rx_ready_i (~s_rx_push_ready) + .clk_i (apb4.pclk), + .rst_n_i (apb4.presetn), + .rx_i (uart.uart_rx_i), + .busy_o (), + .cfg_en_i (1'b1), + .cfg_div_i (s_uart_div_q[`UART_DIV_WIDTH-1:0]), + .cfg_parity_en_i (s_bit_pen), + .cfg_parity_sel_i(s_bit_ps), + .cfg_bits_i (s_bit_wls), + .err_o (s_parity_err), + .err_clr_i (1'b1), + .rx_data_o (s_rx_push_data), + .rx_valid_o (s_rx_push_valid), + .rx_ready_i (~s_rx_push_ready) ); uart_irq #( @@ -194,7 +216,7 @@ module apb4_uart #( .pe_i (s_uart_lsr_q[4]), .rx_elem_i (s_rx_elem), .tx_elem_i (s_tx_elem), - .trg_level_i(s_uart_fcr_q[3:2]), + .trg_level_i(s_bit_rx_trg_levl), .ip_o (s_lsr_ip), .irq_o (uart.irq_o) ); diff --git a/rtl/uart_define.sv b/rtl/uart_define.sv index 8b0335a..5f8406f 100644 --- a/rtl/uart_define.sv +++ b/rtl/uart_define.sv @@ -13,30 +13,30 @@ /* register mapping * UART_LCR: - * BITS: | 31:9 | 8:7 | 6 | 5 | 4:3 | 2 | 1 | 0 | - * FIELDS: | RES | PS | PEN | STB | WLS | PEIE | TXIE | RXIE | - * PERMS: | NONE | RW | RW | RW | RW | RW | RW | RW | - * ---------------------------------------------------------------- + * BITS: | 31:9 | 8:7 | 6 | 5 | 4:3 | 2 | 1 | 0 | + * FIELDS: | RES | PS | PEN | STB | WLS | PEIE | TXIE | RXIE | + * PERMS: | NONE | RW | RW | RW | RW | RW | RW | RW | + * -------------------------------------------------------------- * UART_DIV: * BITS: | 31:16 | 15:0 | * FIELDS: | RES | DIV | * PERMS: | NONE | RW | - * ---------------------------------------------------------------- + * -------------------------------------------------------------- * UART_TRX: * BITS: | 31:8 | 7:0 || BITS: | 31:8 | 7:0 | * FIELDS: | RES | RX || FIELDS: | RES | TX | * PERMS: | NONE | R || PERMS: | NONE | W | - * ---------------------------------------------------------------- + * ------------------------------------------------------------- * UART_FCR: * BITS: | 31:4 | 3:2 | 1 | 0 | * FIELDS: | RES | RX_TRG_LEVL | TF_CLR | RF_CLR | * PERMS: | NONE | W | W | W | - * ---------------------------------------------------------------- + * -------------------------------------------------------------- * UART_LSR: * BITS: | 31:7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | * FIELDS: | RES | TEMT | THRE | PE | DR | PEIP | TXIP | RXIP | * PERMS: | NONE | R | R | R | R | R | R | R | - * ---------------------------------------------------------------- + * -------------------------------------------------------------- */ // verilog_format: off diff --git a/rtl/uart_rx.sv b/rtl/uart_rx.sv index 9cc5949..42f5595 100644 --- a/rtl/uart_rx.sv +++ b/rtl/uart_rx.sv @@ -28,6 +28,7 @@ module uart_rx ( input logic cfg_en_i, input logic [15:0] cfg_div_i, input logic cfg_parity_en_i, + input logic [ 1:0] cfg_parity_sel_i, input logic [ 1:0] cfg_bits_i, output logic err_o, input logic err_clr_i, @@ -120,7 +121,12 @@ module uart_rx ( PARITY: begin s_baudgen_en = 1'b1; if (s_bit_done) begin - if (s_parity_bit_q != reg_rx_sync[2]) s_set_error = 1'b1; + unique case (cfg_parity_sel_i) + 2'b00: if (reg_rx_sync[2] != ~s_parity_bit_q) s_set_error = 1'b1; + 2'b01: if (reg_rx_sync[2] != s_parity_bit_q) s_set_error = 1'b1; + 2'b10: if (reg_rx_sync[2] != 1'b0) s_set_error = 1'b1; + 2'b11: if (reg_rx_sync[2] != 1'b1) s_set_error = 1'b1; + endcase s_fsm_d = STOP_BIT; end end diff --git a/rtl/uart_tx.sv b/rtl/uart_tx.sv index f131ffd..466f08e 100644 --- a/rtl/uart_tx.sv +++ b/rtl/uart_tx.sv @@ -26,8 +26,9 @@ module uart_tx ( output logic tx_o, output logic busy_o, input logic cfg_en_i, - input logic [15:0] cfg_div_i, // NOTE: no parameterization + input logic [15:0] cfg_div_i, // NOTE: no parameterization input logic cfg_parity_en_i, + input logic [ 1:0] cfg_parity_sel_i, input logic [ 1:0] cfg_bits_i, input logic cfg_stop_bits_i, input logic [ 7:0] tx_data_i, @@ -106,7 +107,13 @@ module uart_tx ( end end PARITY: begin - tx_o = s_parity_bit_q; + unique case (cfg_parity_sel_i) + 2'b00: tx_o = ~s_parity_bit_q; + 2'b01: tx_o = s_parity_bit_q; + 2'b10: tx_o = 1'b0; + 2'b11: tx_o = 1'b1; + endcase + s_baudgen_en = 1'b1; if (s_bit_done) s_fsm_d = STOP_BIT_FIRST; end