1// 2// Copyright 2019 Ettus Research, a National Instruments Company 3// 4// SPDX-License-Identifier: LGPL-3.0-or-later 5// 6// Module: axi_ram_fifo_bist_regs 7// 8// Description: 9// 10// Implements the registers for the RAM FIFO BIST logic. 11// 12// Parameters: 13// 14// DATA_W : The width of the data port to use for the AXI4-Stream 15// interface. 16// 17// COUNT_W : Width of internal counters. This must be wide enough so that 18// word, cycle, and and error counters don't overflow during a 19// test. 20// 21// CLK_RATE : The frequency of clk in Hz 22// 23 24module axi_ram_fifo_bist_regs #( 25 parameter DATA_W = 64, 26 parameter COUNT_W = 48, 27 parameter CLK_RATE = 200e6 28) ( 29 input clk, 30 input rst, 31 32 //-------------------------------------------------------------------------- 33 // CTRL Port 34 //-------------------------------------------------------------------------- 35 36 input wire s_ctrlport_req_wr, 37 input wire s_ctrlport_req_rd, 38 input wire [19:0] s_ctrlport_req_addr, 39 input wire [31:0] s_ctrlport_req_data, 40 output reg s_ctrlport_resp_ack, 41 output reg [31:0] s_ctrlport_resp_data, 42 43 //-------------------------------------------------------------------------- 44 // Control and Status 45 //-------------------------------------------------------------------------- 46 47 input wire [COUNT_W-1:0] tx_count, 48 input wire [COUNT_W-1:0] rx_count, 49 input wire [COUNT_W-1:0] error_count, 50 input wire [COUNT_W-1:0] cycle_count, 51 52 output wire [COUNT_W-1:0] num_words, 53 54 output reg start, 55 output reg stop, 56 output reg clear, 57 output reg continuous, 58 input wire running 59); 60 61 `include "axi_ram_fifo_regs.vh" 62 63 localparam BYTES_PER_WORD = DATA_W/8; 64 localparam WORD_SHIFT = $clog2(BYTES_PER_WORD); 65 66 // Make sure DATA_W is a power of 2, or else the word/byte count conversion 67 // logic won't be correct. 68 if (2**$clog2(DATA_W) != DATA_W) begin 69 DATA_W_must_be_a_power_of_2(); 70 end 71 72 // The register logic currently assumes that COUNT_W is at least 33 bits. 73 if (COUNT_W <= 32) begin 74 COUNT_W_must_be_larger_than_32(); 75 end 76 77 wire [19:0] word_addr; 78 wire [63:0] tx_byte_count; 79 wire [63:0] rx_byte_count; 80 reg [63:0] num_bytes = 0; 81 82 reg [31:0] tx_byte_count_hi = 0; 83 reg [31:0] rx_byte_count_hi = 0; 84 reg [31:0] error_count_hi = 0; 85 reg [31:0] cycle_count_hi = 0; 86 87 // Only use the word address to simplify address decoding logic 88 assign word_addr = {s_ctrlport_req_addr[19:2], 2'b00 }; 89 90 // Convert between words and bytes 91 assign tx_byte_count = tx_count << WORD_SHIFT; 92 assign rx_byte_count = rx_count << WORD_SHIFT; 93 assign num_words = num_bytes >> WORD_SHIFT; 94 95 96 always @(posedge clk) begin 97 if (rst) begin 98 s_ctrlport_resp_ack <= 0; 99 start <= 0; 100 stop <= 0; 101 continuous <= 0; 102 clear <= 0; 103 num_bytes <= 0; 104 end else begin 105 // Default values 106 s_ctrlport_resp_ack <= 0; 107 start <= 0; 108 stop <= 0; 109 clear <= 0; 110 111 //----------------------------------------------------------------------- 112 // Read Logic 113 //----------------------------------------------------------------------- 114 115 if (s_ctrlport_req_rd) begin 116 case (word_addr) 117 REG_BIST_CTRL : begin 118 s_ctrlport_resp_data <= 0; 119 s_ctrlport_resp_data[REG_BIST_RUNNING_POS] <= running; 120 s_ctrlport_resp_data[REG_BIST_CONT_POS] <= continuous; 121 s_ctrlport_resp_ack <= 1; 122 end 123 REG_BIST_CLK_RATE : begin 124 s_ctrlport_resp_data <= CLK_RATE; 125 s_ctrlport_resp_ack <= 1; 126 end 127 REG_BIST_NUM_BYTES_LO : begin 128 s_ctrlport_resp_data <= num_bytes[31:0]; 129 s_ctrlport_resp_ack <= 1; 130 end 131 REG_BIST_NUM_BYTES_HI : begin 132 s_ctrlport_resp_data <= num_bytes[63:32]; 133 s_ctrlport_resp_ack <= 1; 134 end 135 REG_BIST_TX_BYTE_COUNT_LO : begin 136 s_ctrlport_resp_data <= tx_byte_count[31:0]; 137 tx_byte_count_hi <= tx_byte_count[63:32]; 138 s_ctrlport_resp_ack <= 1; 139 end 140 REG_BIST_TX_BYTE_COUNT_HI : begin 141 s_ctrlport_resp_data <= tx_byte_count_hi; 142 s_ctrlport_resp_ack <= 1; 143 end 144 REG_BIST_RX_BYTE_COUNT_LO : begin 145 s_ctrlport_resp_data <= rx_byte_count[31:0]; 146 rx_byte_count_hi[COUNT_W-33:0] <= rx_byte_count[COUNT_W-1:32]; 147 s_ctrlport_resp_ack <= 1; 148 end 149 REG_BIST_RX_BYTE_COUNT_HI : begin 150 s_ctrlport_resp_data <= rx_byte_count_hi; 151 s_ctrlport_resp_ack <= 1; 152 end 153 REG_BIST_ERROR_COUNT_LO : begin 154 s_ctrlport_resp_data <= error_count[31:0]; 155 error_count_hi[COUNT_W-33:0] <= error_count[COUNT_W-1:32]; 156 s_ctrlport_resp_ack <= 1; 157 end 158 REG_BIST_ERROR_COUNT_HI : begin 159 s_ctrlport_resp_data <= 0; 160 s_ctrlport_resp_data <= error_count_hi; 161 s_ctrlport_resp_ack <= 1; 162 end 163 REG_BIST_CYCLE_COUNT_LO : begin 164 s_ctrlport_resp_data <= cycle_count[31:0]; 165 cycle_count_hi[COUNT_W-33:0] <= cycle_count[COUNT_W-1:32]; 166 s_ctrlport_resp_ack <= 1; 167 end 168 REG_BIST_CYCLE_COUNT_HI : begin 169 s_ctrlport_resp_data <= 0; 170 s_ctrlport_resp_data <= cycle_count_hi; 171 s_ctrlport_resp_ack <= 1; 172 end 173 endcase 174 end 175 176 177 //----------------------------------------------------------------------- 178 // Write Logic 179 //----------------------------------------------------------------------- 180 181 if (s_ctrlport_req_wr) begin 182 case (word_addr) 183 REG_BIST_CTRL : begin 184 start <= s_ctrlport_req_data[REG_BIST_START_POS]; 185 stop <= s_ctrlport_req_data[REG_BIST_STOP_POS]; 186 clear <= s_ctrlport_req_data[REG_BIST_CLEAR_POS]; 187 continuous <= s_ctrlport_req_data[REG_BIST_CONT_POS]; 188 s_ctrlport_resp_ack <= 1; 189 end 190 REG_BIST_NUM_BYTES_LO : begin 191 // Update only the word-count portion 192 num_bytes[31:WORD_SHIFT] <= s_ctrlport_req_data[31:WORD_SHIFT]; 193 s_ctrlport_resp_ack <= 1; 194 end 195 REG_BIST_NUM_BYTES_HI : begin 196 num_bytes[COUNT_W-1:32] <= s_ctrlport_req_data[COUNT_W-33:0]; 197 s_ctrlport_resp_ack <= 1; 198 end 199 endcase 200 end 201 202 end 203 end 204 205endmodule 206 207