mirror of
https://github.com/pConst/basic_verilog.git
synced 2025-02-04 07:12:56 +08:00
Added simple UART logger
This commit is contained in:
parent
c6d4f60bca
commit
68b33a10d4
298
axi4l_logger.sv
Executable file
298
axi4l_logger.sv
Executable file
@ -0,0 +1,298 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// axi4l_logger.sv
|
||||||
|
// published as part of https://github.com/pConst/basic_verilog
|
||||||
|
// Konstantin Pavlov, pavlovconst@gmail.com
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// INFO ------------------------------------------------------------------------
|
||||||
|
// AXI4-Lite logger
|
||||||
|
// Sniffs all AXI transactions and stores address and data to fifo
|
||||||
|
//
|
||||||
|
// - optimized for `AXI_ADDR_WIDTH = 32 and `AXI_DATA_WIDTH = 32
|
||||||
|
//
|
||||||
|
|
||||||
|
/* --- INSTANTIATION TEMPLATE BEGIN ---
|
||||||
|
|
||||||
|
axi4l_logger AL (
|
||||||
|
.clk_axi( ),
|
||||||
|
.anrst_axi( ),
|
||||||
|
|
||||||
|
// axi interface here
|
||||||
|
|
||||||
|
.clk( ),
|
||||||
|
|
||||||
|
.empty( )
|
||||||
|
.r_req( ),
|
||||||
|
.r_rnw( ),
|
||||||
|
.r_addr( ),
|
||||||
|
.r_data( )
|
||||||
|
);
|
||||||
|
|
||||||
|
--- INSTANTIATION TEMPLATE END ---*/
|
||||||
|
|
||||||
|
|
||||||
|
module axi4l_logger #( parameter
|
||||||
|
bit [`AXI_ADDR_WIDTH-1:0] REG_ADDRESS_FROM = '0, // register address
|
||||||
|
bit [`AXI_ADDR_WIDTH-1:0] REG_ADDRESS_TO = '1 // space to log
|
||||||
|
)(
|
||||||
|
input clk_axi, // axi clock
|
||||||
|
input anrst_axi, // axi async reset (inversed)
|
||||||
|
|
||||||
|
input [`AXI_ADDR_WIDTH-1:0] s_axi_araddr, // axil
|
||||||
|
input [1:0] s_axi_arburst,
|
||||||
|
input [3:0] s_axi_arcache,
|
||||||
|
input [`AXI_LEN_WIDTH-1:0] s_axi_arlen,
|
||||||
|
input [0:0] s_axi_arlock,
|
||||||
|
input [2:0] s_axi_arprot, // axil // NU here
|
||||||
|
input [3:0] s_axi_arqos,
|
||||||
|
input s_axi_arready, // axil
|
||||||
|
input [3:0] s_axi_arregion,
|
||||||
|
input [`AXI_SIZE_WIDTH-1:0] s_axi_arsize,
|
||||||
|
input s_axi_arvalid, // axil
|
||||||
|
|
||||||
|
input [`AXI_ADDR_WIDTH-1:0] s_axi_awaddr, // axil
|
||||||
|
input [1:0] s_axi_awburst,
|
||||||
|
input [3:0] s_axi_awcache,
|
||||||
|
input [`AXI_LEN_WIDTH-1:0] s_axi_awlen,
|
||||||
|
input [0:0] s_axi_awlock,
|
||||||
|
input [2:0] s_axi_awprot, // axil // NU here
|
||||||
|
input [3:0] s_axi_awqos,
|
||||||
|
input s_axi_awready, // axil
|
||||||
|
input [3:0] s_axi_awregion,
|
||||||
|
input [`AXI_SIZE_WIDTH-1:0] s_axi_awsize,
|
||||||
|
input s_axi_awvalid, // axil
|
||||||
|
|
||||||
|
input s_axi_bready, // axil
|
||||||
|
input [1:0] s_axi_bresp, // axil
|
||||||
|
input s_axi_bvalid, // axil
|
||||||
|
|
||||||
|
input [`AXI_DATA_WIDTH-1:0] s_axi_rdata, // axil
|
||||||
|
input s_axi_rlast,
|
||||||
|
input s_axi_rready, // axil
|
||||||
|
input [1:0] s_axi_rresp, // axil
|
||||||
|
input s_axi_rvalid, // axil
|
||||||
|
|
||||||
|
input [`AXI_DATA_WIDTH-1:0] s_axi_wdata, // axil
|
||||||
|
input s_axi_wlast,
|
||||||
|
input s_axi_wready, // axil
|
||||||
|
input [`AXI_DATA_BYTES-1:0] s_axi_wstrb, // axil
|
||||||
|
input s_axi_wvalid, // axil
|
||||||
|
|
||||||
|
// fifo output interface
|
||||||
|
input clk,
|
||||||
|
output empty,
|
||||||
|
input r_req,
|
||||||
|
|
||||||
|
output r_rnw,
|
||||||
|
output [`AXI_ADDR_WIDTH-1:0] r_addr,
|
||||||
|
output [`AXI_DATA_WIDTH-1:0] r_data
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
logic aw_w_req; // axi addr write request
|
||||||
|
logic ar_w_req; // axi addr read request
|
||||||
|
|
||||||
|
logic aw_w_req_d1;
|
||||||
|
logic ar_w_req_d1;
|
||||||
|
always_ff @( posedge clk_axi or negedge anrst_axi ) begin
|
||||||
|
if( ~anrst_axi ) begin
|
||||||
|
aw_w_req_d1 <= 1'b0;
|
||||||
|
ar_w_req_d1 <= 1'b0;
|
||||||
|
end else begin
|
||||||
|
aw_w_req_d1 <= aw_w_req;
|
||||||
|
ar_w_req_d1 <= ar_w_req;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// WRITE =======================================================================
|
||||||
|
|
||||||
|
logic aw_en = 1'b1;
|
||||||
|
always_ff @( posedge clk_axi or negedge anrst_axi ) begin
|
||||||
|
if ( ~anrst_axi ) begin
|
||||||
|
aw_en <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
if (~s_axi_awready && s_axi_awvalid && s_axi_wvalid && aw_en) begin
|
||||||
|
aw_en <= 1'b0;
|
||||||
|
end else if (s_axi_bready && s_axi_bvalid) begin
|
||||||
|
aw_en <= 1'b1;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
logic [`AXI_DATA_WIDTH-1:0] s_axi_awaddr_buf = '0;
|
||||||
|
always_ff @( posedge clk_axi or negedge anrst_axi ) begin
|
||||||
|
if ( ~anrst_axi ) begin
|
||||||
|
s_axi_awaddr_buf[`AXI_DATA_WIDTH-1:0] <= '0;
|
||||||
|
end else begin
|
||||||
|
if (~s_axi_awready && s_axi_awvalid && s_axi_wvalid && aw_en) begin
|
||||||
|
s_axi_awaddr_buf[`AXI_DATA_WIDTH-1:0] <= s_axi_awaddr[`AXI_DATA_WIDTH-1:0];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
aw_w_req = s_axi_wready && s_axi_wvalid && s_axi_awready && s_axi_awvalid &&
|
||||||
|
(s_axi_awaddr_buf[`AXI_ADDR_WIDTH-1:0] >= REG_ADDRESS_FROM[`AXI_ADDR_WIDTH-1:0]) &&
|
||||||
|
(s_axi_awaddr_buf[`AXI_ADDR_WIDTH-1:0] <= REG_ADDRESS_TO[`AXI_ADDR_WIDTH-1:0]);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// READ ========================================================================
|
||||||
|
|
||||||
|
logic [`AXI_ADDR_WIDTH-1:0] s_axi_araddr_buf = '0;
|
||||||
|
always_ff @( posedge clk_axi or negedge anrst_axi ) begin
|
||||||
|
if ( ~anrst_axi ) begin
|
||||||
|
s_axi_araddr_buf[`AXI_ADDR_WIDTH-1:0] <= '0;
|
||||||
|
end else begin
|
||||||
|
if (~s_axi_arready && s_axi_arvalid) begin
|
||||||
|
s_axi_araddr_buf[`AXI_ADDR_WIDTH-1:0] <= s_axi_araddr[`AXI_ADDR_WIDTH-1:0];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always_comb begin
|
||||||
|
ar_w_req = s_axi_arready && s_axi_arvalid && ~s_axi_rvalid &&
|
||||||
|
(s_axi_araddr_buf[`AXI_ADDR_WIDTH-1:0] >= REG_ADDRESS_FROM[`AXI_ADDR_WIDTH-1:0]) &&
|
||||||
|
(s_axi_araddr_buf[`AXI_ADDR_WIDTH-1:0] <= REG_ADDRESS_TO[`AXI_ADDR_WIDTH-1:0]);
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
// FIFO ========================================================================
|
||||||
|
|
||||||
|
// fifo inputs
|
||||||
|
logic [31:0] w_addr_f;
|
||||||
|
logic [31:0] w_data_f;
|
||||||
|
logic [31:0] w_rnwr_f;
|
||||||
|
always_comb begin
|
||||||
|
if( aw_w_req_d1 ) begin
|
||||||
|
w_addr_f[31:0] = s_axi_awaddr_buf[31:0];
|
||||||
|
w_data_f[31:0] = s_axi_wdata[31:0];
|
||||||
|
w_rnwr_f[31:0] = '0;
|
||||||
|
end else if( ar_w_req_d1 ) begin
|
||||||
|
w_addr_f[31:0] = s_axi_araddr_buf[31:0];
|
||||||
|
w_data_f[31:0] = s_axi_rdata[31:0];
|
||||||
|
w_rnwr_f[31:0] = 32'b1;
|
||||||
|
end else begin
|
||||||
|
w_addr_f[31:0] = '0;
|
||||||
|
w_data_f[31:0] = '0;
|
||||||
|
w_rnwr_f[31:0] = '0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// fifo outputs
|
||||||
|
logic [31:0] r_addr_f;
|
||||||
|
logic [31:0] r_data_f;
|
||||||
|
logic [31:0] r_rnwr_f;
|
||||||
|
|
||||||
|
FIFO18E1 #(
|
||||||
|
.ALMOST_EMPTY_OFFSET ( 13'h0006 ), // min. value is 6 for FWFT mode, Sets the almost empty threshold
|
||||||
|
.ALMOST_FULL_OFFSET ( 13'h0005 ), // min. value is 4, Sets almost full threshold
|
||||||
|
.DATA_WIDTH ( 36 ), // Sets data width to 4-36
|
||||||
|
.DO_REG ( 1 ), // Enable output register ( 1-0 ) Must be 1 if EN_SYN = FALSE
|
||||||
|
.EN_SYN ( "FALSE" ), // Specifies FIFO as dual-clock ( FALSE ) or Synchronous ( TRUE )
|
||||||
|
.FIFO_MODE ( "FIFO18_36" ), // Sets mode to FIFO18 or FIFO18_36
|
||||||
|
.FIRST_WORD_FALL_THROUGH ( "TRUE" ), // Sets the FIFO FWFT to FALSE, TRUE
|
||||||
|
.INIT ( 36'h000000000 ), // Initial values on output port
|
||||||
|
.SIM_DEVICE ( "7SERIES" ), // Must be set to "7SERIES" for simulation behavior
|
||||||
|
.SRVAL ( 36'h000000000 ) // Set/Reset value for output port
|
||||||
|
) addr_fifo_b (
|
||||||
|
.RST ( ~anrst_axi ), // 1-bit input: Asynchronous Reset
|
||||||
|
.RSTREG ( 1'b0 ), // 1-bit input: Output register set/reset
|
||||||
|
|
||||||
|
.WRCLK ( clk_axi ), // 1-bit input: Write clock
|
||||||
|
.WREN ( aw_w_req_d1 || ar_w_req_d1 ), // 1-bit input: Write enable
|
||||||
|
.DI ( w_addr_f[31:0] ), // 32-bit input: Data input
|
||||||
|
.DIP ( 4'b0 ), // 4-bit input: Parity input
|
||||||
|
.FULL ( ), // 1-bit output: Full flag
|
||||||
|
.ALMOSTFULL ( ), // 1-bit output: Almost full flag
|
||||||
|
.WRCOUNT ( ), // 12-bit output: Write count
|
||||||
|
.WRERR ( ), // 1-bit output: Write error
|
||||||
|
|
||||||
|
.RDCLK ( clk ), // 1-bit input: Read clock
|
||||||
|
.REGCE ( 1'b1 ), // 1-bit input: Clock enable
|
||||||
|
.RDEN ( r_req ), // 1-bit input: Read enable
|
||||||
|
.DO ( r_addr_f[31:0] ), // 32-bit output: Data output
|
||||||
|
.DOP ( ), // 4-bit output: Parity data output
|
||||||
|
.EMPTY ( empty ), // 1-bit output: Empty flag
|
||||||
|
.ALMOSTEMPTY ( ), // 1-bit output: Almost empty flag
|
||||||
|
.RDCOUNT ( ), // 12-bit output: Read count
|
||||||
|
.RDERR ( ) // 1-bit output: Read error
|
||||||
|
);
|
||||||
|
|
||||||
|
FIFO18E1 #(
|
||||||
|
.ALMOST_EMPTY_OFFSET ( 13'h0006 ), // min. value is 6 for FWFT mode, Sets the almost empty threshold
|
||||||
|
.ALMOST_FULL_OFFSET ( 13'h0005 ), // min. value is 4, Sets almost full threshold
|
||||||
|
.DATA_WIDTH ( 36 ), // Sets data width to 4-36
|
||||||
|
.DO_REG ( 1 ), // Enable output register ( 1-0 ) Must be 1 if EN_SYN = FALSE
|
||||||
|
.EN_SYN ( "FALSE" ), // Specifies FIFO as dual-clock ( FALSE ) or Synchronous ( TRUE )
|
||||||
|
.FIFO_MODE ( "FIFO18_36" ), // Sets mode to FIFO18 or FIFO18_36
|
||||||
|
.FIRST_WORD_FALL_THROUGH ( "TRUE" ), // Sets the FIFO FWFT to FALSE, TRUE
|
||||||
|
.INIT ( 36'h000000000 ), // Initial values on output port
|
||||||
|
.SIM_DEVICE ( "7SERIES" ), // Must be set to "7SERIES" for simulation behavior
|
||||||
|
.SRVAL ( 36'h000000000 ) // Set/Reset value for output port
|
||||||
|
) data_fifo_b (
|
||||||
|
.RST ( ~anrst_axi ), // 1-bit input: Asynchronous Reset
|
||||||
|
.RSTREG ( 1'b0 ), // 1-bit input: Output register set/reset
|
||||||
|
|
||||||
|
.WRCLK ( clk_axi ), // 1-bit input: Write clock
|
||||||
|
.WREN ( aw_w_req_d1 || ar_w_req_d1 ), // 1-bit input: Write enable
|
||||||
|
.DI ( w_data_f[31:0] ), // 32-bit input: Data input
|
||||||
|
.DIP ( 4'b0 ), // 4-bit input: Parity input
|
||||||
|
.FULL ( ), // 1-bit output: Full flag
|
||||||
|
.ALMOSTFULL ( ), // 1-bit output: Almost full flag
|
||||||
|
.WRCOUNT ( ), // 12-bit output: Write count
|
||||||
|
.WRERR ( ), // 1-bit output: Write error
|
||||||
|
|
||||||
|
.RDCLK ( clk ), // 1-bit input: Read clock
|
||||||
|
.REGCE ( 1'b1 ), // 1-bit input: Clock enable
|
||||||
|
.RDEN ( r_req ), // 1-bit input: Read enable
|
||||||
|
.DO ( r_data_f[31:0] ), // 32-bit output: Data output
|
||||||
|
.DOP ( ), // 4-bit output: Parity data output
|
||||||
|
.EMPTY ( ), // 1-bit output: Empty flag
|
||||||
|
.ALMOSTEMPTY ( ), // 1-bit output: Almost empty flag
|
||||||
|
.RDCOUNT ( ), // 12-bit output: Read count
|
||||||
|
.RDERR ( ) // 1-bit output: Read error
|
||||||
|
);
|
||||||
|
|
||||||
|
FIFO18E1 #(
|
||||||
|
.ALMOST_EMPTY_OFFSET ( 13'h0006 ), // min. value is 6 for FWFT mode, Sets the almost empty threshold
|
||||||
|
.ALMOST_FULL_OFFSET ( 13'h0005 ), // min. value is 4, Sets almost full threshold
|
||||||
|
.DATA_WIDTH ( 36 ), // Sets data width to 4-36
|
||||||
|
.DO_REG ( 1 ), // Enable output register ( 1-0 ) Must be 1 if EN_SYN = FALSE
|
||||||
|
.EN_SYN ( "FALSE" ), // Specifies FIFO as dual-clock ( FALSE ) or Synchronous ( TRUE )
|
||||||
|
.FIFO_MODE ( "FIFO18_36" ), // Sets mode to FIFO18 or FIFO18_36
|
||||||
|
.FIRST_WORD_FALL_THROUGH ( "TRUE" ), // Sets the FIFO FWFT to FALSE, TRUE
|
||||||
|
.INIT ( 36'h000000000 ), // Initial values on output port
|
||||||
|
.SIM_DEVICE ( "7SERIES" ), // Must be set to "7SERIES" for simulation behavior
|
||||||
|
.SRVAL ( 36'h000000000 ) // Set/Reset value for output port
|
||||||
|
) rnmr_fifo_b (
|
||||||
|
.RST ( ~anrst_axi ), // 1-bit input: Asynchronous Reset
|
||||||
|
.RSTREG ( 1'b0 ), // 1-bit input: Output register set/reset
|
||||||
|
|
||||||
|
.WRCLK ( clk_axi ), // 1-bit input: Write clock
|
||||||
|
.WREN ( aw_w_req_d1 || ar_w_req_d1 ), // 1-bit input: Write enable
|
||||||
|
.DI ( w_rnwr_f[31:0] ), // 32-bit input: Data input
|
||||||
|
.DIP ( 4'b0 ), // 4-bit input: Parity input
|
||||||
|
.FULL ( ), // 1-bit output: Full flag
|
||||||
|
.ALMOSTFULL ( ), // 1-bit output: Almost full flag
|
||||||
|
.WRCOUNT ( ), // 12-bit output: Write count
|
||||||
|
.WRERR ( ), // 1-bit output: Write error
|
||||||
|
|
||||||
|
.RDCLK ( clk ), // 1-bit input: Read clock
|
||||||
|
.REGCE ( 1'b1 ), // 1-bit input: Clock enable
|
||||||
|
.RDEN ( r_req ), // 1-bit input: Read enable
|
||||||
|
.DO ( r_rnwr_f[31:0] ), // 32-bit output: Data output
|
||||||
|
.DOP ( ), // 4-bit output: Parity data output
|
||||||
|
.EMPTY ( ), // 1-bit output: Empty flag
|
||||||
|
.ALMOSTEMPTY ( ), // 1-bit output: Almost empty flag
|
||||||
|
.RDCOUNT ( ), // 12-bit output: Read count
|
||||||
|
.RDERR ( ) // 1-bit output: Read error
|
||||||
|
);
|
||||||
|
|
||||||
|
assign r_rnw = r_rnwr_f[0];
|
||||||
|
assign r_addr[31:0] = r_addr_f[31:0];
|
||||||
|
assign r_data[31:0] = r_data_f[31:0];
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
327
uart_debug_printer.sv
Executable file
327
uart_debug_printer.sv
Executable file
@ -0,0 +1,327 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// uart_debug_printer.sv
|
||||||
|
// published as part of https://github.com/pConst/basic_verilog
|
||||||
|
// Konstantin Pavlov, pavlovconst@gmail.com
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// INFO ------------------------------------------------------------------------
|
||||||
|
// Debug data printer to UART terminal
|
||||||
|
// This particular module prints out one R/W bit and two 32-bit words in HEX format
|
||||||
|
// Could be easily adapted for other data formats
|
||||||
|
//
|
||||||
|
// Features:
|
||||||
|
// - fifo-like input interface
|
||||||
|
// - built-in UART transmitter
|
||||||
|
// - compatible with all sorts of UART-to-USB dongles
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
/* --- INSTANTIATION TEMPLATE BEGIN ---
|
||||||
|
|
||||||
|
uart_debug_printer #(
|
||||||
|
.CLK_HZ( 100_000_000 ),
|
||||||
|
.BAUD( 115200 )
|
||||||
|
) UP (
|
||||||
|
.clk( ),
|
||||||
|
.anrst( ),
|
||||||
|
|
||||||
|
.empty( ),
|
||||||
|
.r_req( ),
|
||||||
|
.r_rnw( ), // fifo data, 1 bit
|
||||||
|
.r_addr( ), // fifo data, 32 bit
|
||||||
|
.r_data( ), // fifo data, 32 bit
|
||||||
|
|
||||||
|
.uart_txd( )
|
||||||
|
);
|
||||||
|
|
||||||
|
--- INSTANTIATION TEMPLATE END ---*/
|
||||||
|
|
||||||
|
|
||||||
|
// synopsys translate_off
|
||||||
|
`define SIMULATION yes
|
||||||
|
// synopsys translate_on
|
||||||
|
|
||||||
|
module uart_debug_printer #( parameter
|
||||||
|
CLK_HZ = 100_000_000,
|
||||||
|
BAUD = 115200
|
||||||
|
)(
|
||||||
|
input clk, // clock 100MHz
|
||||||
|
input anrst, // async reset
|
||||||
|
|
||||||
|
// fifo output
|
||||||
|
input empty, // data valid flag
|
||||||
|
output logic r_req = 1'b0, // data request acknowledge
|
||||||
|
input r_rnw, // read/nwrite bit
|
||||||
|
input [31:0] r_addr, // first 32 bit word
|
||||||
|
input [31:0] r_data, // second 32 bit word
|
||||||
|
|
||||||
|
// UART TX
|
||||||
|
output uart_txd // UART tx pin
|
||||||
|
);
|
||||||
|
|
||||||
|
logic tx_start = 1'b0;
|
||||||
|
logic tx_busy;
|
||||||
|
|
||||||
|
// character sequencer
|
||||||
|
logic [7:0] seq_cntr = '0;
|
||||||
|
logic [7:0] tx_char = '0;
|
||||||
|
always_ff @( posedge clk or negedge anrst ) begin
|
||||||
|
if ( ~anrst ) begin
|
||||||
|
r_req = 1'b0;
|
||||||
|
tx_start = 1'b0;
|
||||||
|
|
||||||
|
seq_cntr[7:0] <= '0;
|
||||||
|
tx_char[7:0] <= '0;
|
||||||
|
end else begin
|
||||||
|
case ( seq_cntr[7:0] )
|
||||||
|
|
||||||
|
7'd0: begin
|
||||||
|
if( ~empty && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= (r_rnw)?(7'd82):(7'd87); // "R"/"W" symbol
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'd1: begin
|
||||||
|
if( ~tx_start && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= 7'd32; // "_" divider symbol =======================
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
7'd2: begin
|
||||||
|
if( ~tx_start && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= hex2ascii(r_addr[31:28]);
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'd3: begin
|
||||||
|
if( ~tx_start && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= hex2ascii(r_addr[27:24]);
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'd4: begin
|
||||||
|
if( ~tx_start && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= hex2ascii(r_addr[23:20]);
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'd5: begin
|
||||||
|
if( ~tx_start && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= hex2ascii(r_addr[19:16]);
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'd6: begin
|
||||||
|
if( ~tx_start && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= 7'd95; // "_" symbol
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'd7: begin
|
||||||
|
if( ~tx_start && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= hex2ascii(r_addr[15:12]);
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'd8: begin
|
||||||
|
if( ~tx_start && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= hex2ascii(r_addr[11:8]);
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'd9: begin
|
||||||
|
if( ~tx_start && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= hex2ascii(r_addr[7:4]);
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'd10: begin
|
||||||
|
if( ~tx_start && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= hex2ascii(r_addr[3:0]);
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
7'd11: begin
|
||||||
|
if( ~tx_start && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= 7'd32; // "-" divider symbol =======================
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
7'd12: begin
|
||||||
|
if( ~tx_start && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= hex2ascii(r_data[31:28]);
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'd13: begin
|
||||||
|
if( ~tx_start && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= hex2ascii(r_data[27:24]);
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'd14: begin
|
||||||
|
if( ~tx_start && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= hex2ascii(r_data[23:20]);
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'd15: begin
|
||||||
|
if( ~tx_start && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= hex2ascii(r_data[19:16]);
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'd16: begin
|
||||||
|
if( ~tx_start && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= 7'd95; // "_" symbol
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'd17: begin
|
||||||
|
if( ~tx_start && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= hex2ascii(r_data[15:12]);
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'd18: begin
|
||||||
|
if( ~tx_start && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= hex2ascii(r_data[11:8]);
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'd19: begin
|
||||||
|
if( ~tx_start && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= hex2ascii(r_data[7:4]);
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
7'd20: begin
|
||||||
|
if( ~tx_start && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= hex2ascii(r_data[3:0]);
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
7'd21: begin
|
||||||
|
if( ~tx_start && ~tx_busy ) begin
|
||||||
|
tx_char[7:0] <= 7'd13; // "CR" symbol
|
||||||
|
seq_cntr[7:0] <= seq_cntr[7:0] + 1'b1;
|
||||||
|
r_req <= 1'b1; // fifo data ack begin
|
||||||
|
tx_start <= 1'b1;
|
||||||
|
end else begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
7'd22: begin
|
||||||
|
if( ~tx_busy ) begin
|
||||||
|
tx_start <= 1'b0;
|
||||||
|
seq_cntr[7:0] <= '0;
|
||||||
|
end
|
||||||
|
r_req <= 1'b0; // fifo data ack end
|
||||||
|
end
|
||||||
|
|
||||||
|
default : seq_cntr[7:0] <= '0;
|
||||||
|
endcase
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
uart_tx #(
|
||||||
|
`ifdef SIMULATION
|
||||||
|
.CLK_HZ( 100 ),
|
||||||
|
.BAUD( 10 )
|
||||||
|
`else
|
||||||
|
.CLK_HZ( CLK_HZ ), // in Hertz
|
||||||
|
.BAUD( BAUD ) // max. BAUD is CLK_HZ / 2
|
||||||
|
`endif
|
||||||
|
) uart_tx_b (
|
||||||
|
.clk( clk ),
|
||||||
|
.nrst( 1'b1 ),
|
||||||
|
//.tx_do_sample( ),
|
||||||
|
.tx_data( tx_char[7:0] ),
|
||||||
|
.tx_start( tx_start ),
|
||||||
|
.tx_busy( tx_busy ),
|
||||||
|
.txd( uart_txd )
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
function [7:0] hex2ascii(
|
||||||
|
input [3:0] hex
|
||||||
|
);
|
||||||
|
if( hex[3:0] < 4'hA ) begin
|
||||||
|
hex2ascii[7:0] = hex[3:0] + 7'd48; // 0 hex -> 48 ascii
|
||||||
|
end else begin
|
||||||
|
hex2ascii[7:0] = hex[3:0] + 7'd55; // A hex -> 65 ascii
|
||||||
|
end // if
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user