622 lines
28 KiB
Verilog
622 lines
28 KiB
Verilog
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Filename: spd_reader.v
|
|
// Project: Serial Presence Detect (SPD) Reader for UberDDR3
|
|
//
|
|
// Purpose: Communicates with the SPD (Serial Presence Detect) chip on the
|
|
// DDR3 DIMM using the I2C protocol to retrieve essential timing parameters
|
|
// and configuration details required by UberDDR3. The SPD report will be
|
|
// reported via the UART line.
|
|
//
|
|
// Engineer: Angelo C. Jacobo
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Copyright (C) 2023-2025 Angelo Jacobo
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published by
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
// (at your option) any later version.
|
|
//
|
|
// This program is distributed in the hope that it will be useful,
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
// GNU General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
`default_nettype none
|
|
`timescale 1ns / 1ps
|
|
|
|
module spd_reader (
|
|
// clock and reset
|
|
input wire i_clk,
|
|
input wire i_rst_n,
|
|
// i2c interface
|
|
inout wire i2c_scl,
|
|
inout wire i2c_sda,
|
|
// state of spd reader
|
|
(* mark_debug = "true" *) output reg find_i2c_address_done,
|
|
(* mark_debug = "true" *) output reg read_spd_done,
|
|
// uart interface
|
|
output wire uart_tx
|
|
);
|
|
|
|
localparam I2C_ADDRESS = 7'h30;
|
|
localparam IDLE = 0,
|
|
READ_ADDRESS = 1,
|
|
READ_BYTE = 1,
|
|
SEND_BYTE = 1,
|
|
WAIT_ACK = 2,
|
|
WAIT_SEND = 2,
|
|
DONE_FIND_ADDRESS = 3,
|
|
UART_SEND = 3,
|
|
WAIT_UART_DONE = 4;
|
|
|
|
(* mark_debug = "true" *) reg[1:0] state_find_i2c_address;
|
|
(* mark_debug = "true" *) reg[6:0] i2c_address;
|
|
|
|
// i2c master interface
|
|
reg enable;
|
|
reg read_write;
|
|
reg[7:0] register_address;
|
|
reg[6:0] device_address;
|
|
wire[7:0] miso_data;
|
|
wire busy;
|
|
wire slave_nack;
|
|
(* mark_debug = "true" *) reg nack_unexpected_err;
|
|
(* mark_debug = "true" *) reg[2:0] state_read_spd;
|
|
(* mark_debug = "true" *) reg[5:0] byte_address; // read until byte 63
|
|
(* mark_debug = "true" *) reg[7:0] byte_data[63:0];
|
|
// uart interface
|
|
wire uart_tx_busy;
|
|
reg uart_tx_en;
|
|
reg[7:0] uart_tx_data;
|
|
reg[30*8-1:0] uart_text; // max of 30 chars
|
|
reg[2:0] state_uart_send;
|
|
reg uart_start_send;
|
|
reg[9:0] uart_text_length,uart_text_length_index;
|
|
reg uart_send_done;
|
|
reg skip_byte;
|
|
reg[7:0] mtb_dividend, mtb_divisor;
|
|
wire[7:0] mtb;
|
|
reg[3:0] tras_high;
|
|
|
|
// initialize in case fpga starts with no reset
|
|
initial begin
|
|
state_find_i2c_address = IDLE;
|
|
find_i2c_address_done = 0;
|
|
enable = 1'b0;
|
|
read_write = 1'b0;
|
|
register_address = 8'd0;
|
|
i2c_address = 7'd0;
|
|
read_spd_done = 1'b0;
|
|
nack_unexpected_err = 1'b0;
|
|
state_read_spd = IDLE;
|
|
byte_address = 6'h00;
|
|
state_uart_send = IDLE;
|
|
uart_text_length_index = 0;
|
|
uart_tx_en = 0;
|
|
uart_send_done = 0;
|
|
uart_tx_data = 0;
|
|
uart_start_send = 0;
|
|
uart_text_length = 0;
|
|
uart_text = {(30*8){1'b0}};
|
|
skip_byte = 0;
|
|
mtb_dividend = 0;
|
|
mtb_divisor = 0;
|
|
tras_high = 0;
|
|
end
|
|
|
|
// FSM for I2C
|
|
always @(posedge i_clk, negedge i_rst_n) begin
|
|
if(!i_rst_n) begin
|
|
state_find_i2c_address <= IDLE;
|
|
find_i2c_address_done <= 0;
|
|
enable <= 1'b0;
|
|
read_write <= 1'b0;
|
|
register_address <= 8'd0;
|
|
i2c_address <= 7'd0;
|
|
read_spd_done <= 1'b0;
|
|
nack_unexpected_err <= 1'b0;
|
|
state_read_spd <= IDLE;
|
|
byte_address <= 6'h00;
|
|
uart_start_send <= 0;
|
|
uart_text_length = 0;
|
|
uart_text = {(30*8){1'b0}};
|
|
skip_byte <= 1'b0;
|
|
mtb_dividend <= 0;
|
|
mtb_divisor <= 0;
|
|
tras_high <= 0;
|
|
end
|
|
else begin
|
|
// Find I2C Address of SPD
|
|
case(state_find_i2c_address)
|
|
IDLE: if(!find_i2c_address_done) begin
|
|
state_find_i2c_address <= READ_ADDRESS;
|
|
i2c_address <= 7'h01; // start brute force find i2c address from 1 (0 might be general call)
|
|
end
|
|
READ_ADDRESS: if(!busy) begin
|
|
enable <= 1'b1;
|
|
read_write <= 1'b1; // read i2c
|
|
register_address <= 8'h00; // just always read byte 0
|
|
device_address <= i2c_address;
|
|
state_find_i2c_address <= WAIT_ACK;
|
|
end
|
|
WAIT_ACK: if(!busy && !enable) begin
|
|
if(slave_nack) begin // if wrong i2c_address
|
|
i2c_address <= i2c_address + 1; // increment i2c address
|
|
state_find_i2c_address <= READ_ADDRESS;
|
|
end
|
|
else begin // I2C acks so i2c_address is correct!
|
|
uart_start_send <= 1'b1;
|
|
uart_text_length <= 18;
|
|
uart_text[30*8-1:8*3] <= "I2C Address: 0x";
|
|
uart_text[8*3-1:8*2] <= hex_to_ascii(i2c_address[6:4]);
|
|
uart_text[8*2-1:8*1] <= hex_to_ascii(i2c_address[3:0]);
|
|
uart_text[7:0] <= 8'h0a;
|
|
state_find_i2c_address <= DONE_FIND_ADDRESS;
|
|
end
|
|
end
|
|
else begin
|
|
enable <= 1'b0;
|
|
end
|
|
DONE_FIND_ADDRESS: if(uart_send_done) begin
|
|
state_find_i2c_address <= IDLE;
|
|
find_i2c_address_done <= 1'b1;
|
|
end
|
|
else begin
|
|
uart_start_send <= 1'b0;
|
|
end
|
|
default: state_find_i2c_address <= IDLE;
|
|
endcase
|
|
|
|
// read bytes from SPD
|
|
case(state_read_spd)
|
|
IDLE: if(find_i2c_address_done && !read_spd_done && !nack_unexpected_err) begin // start read SPD only once i2c address is found
|
|
state_read_spd <= READ_BYTE;
|
|
byte_address <= 6'h00; // start read from byte 0
|
|
uart_start_send <= 1'b0;
|
|
skip_byte <= 1'b0;
|
|
end
|
|
READ_BYTE: if(!busy) begin // if not busy, send i2c read transaction
|
|
enable <= 1'b1;
|
|
read_write <= 1'b1; // read i2c
|
|
register_address <= {2'b00,byte_address};
|
|
device_address <= i2c_address;
|
|
state_read_spd <= WAIT_ACK;
|
|
end
|
|
WAIT_ACK: if(!busy && !enable) begin
|
|
if(slave_nack) begin // if i2c_address NACKS, then something is wrong, raise nack_unexpected_err
|
|
nack_unexpected_err <= 1'b1;
|
|
state_read_spd <= IDLE;
|
|
end
|
|
else begin // I2C acks so send via UART the received data
|
|
state_read_spd <= UART_SEND;
|
|
byte_data[byte_address] <= miso_data;
|
|
end
|
|
end
|
|
else begin
|
|
enable <= 1'b0;
|
|
end
|
|
UART_SEND: begin
|
|
case(byte_address)
|
|
0: begin
|
|
uart_start_send <= 1'b1;
|
|
uart_text_length <= 29;
|
|
uart_text[30*8-1:8*29] <= 8'h0a;
|
|
uart_text[29*8-1:8] <= "------ START SPD READ ------";
|
|
uart_text[7:0] <= 8'h0a;
|
|
end
|
|
1: begin
|
|
uart_start_send <= 1'b1;
|
|
uart_text_length <= 18;
|
|
uart_text[30*8-1:8*4] <= "SPD Revision: ";
|
|
uart_text[8*4-1:8*3] <= hex_to_ascii(miso_data[7:4]);
|
|
uart_text[8*3-1:8*2] <= ".";
|
|
uart_text[8*2-1:8*1] <= hex_to_ascii(miso_data[3:0]);
|
|
uart_text[7:0] <= 8'h0a;
|
|
end
|
|
2: begin
|
|
if(miso_data == 8'h0b) begin
|
|
uart_start_send <= 1'b1;
|
|
uart_text_length <= 22;
|
|
uart_text[30*8-1:8] <= "DRAM Type: DDR3 SDRAM";
|
|
uart_text[7:0] <= 8'h0a;
|
|
end
|
|
else begin
|
|
uart_start_send <= 1'b1;
|
|
uart_text_length <= 21;
|
|
uart_text[30*8-1:8] <= "DRAM Type: NOT DDR3!";
|
|
uart_text[7:0] <= 8'h0a;
|
|
end
|
|
end
|
|
3: begin
|
|
case(miso_data)
|
|
8'h00: begin
|
|
uart_start_send <= 1'b1;
|
|
uart_text_length <= 24;
|
|
uart_text[30*8-1:8] <= "Module Type: Undefined!";
|
|
uart_text[7:0] <= 8'h0a;
|
|
end
|
|
8'h01: begin
|
|
uart_start_send <= 1'b1;
|
|
uart_text_length <= 19;
|
|
uart_text[30*8-1:8] <= "Module Type: RDIMM";
|
|
uart_text[7:0] <= 8'h0a;
|
|
end
|
|
8'h02: begin
|
|
uart_start_send <= 1'b1;
|
|
uart_text_length <= 19;
|
|
uart_text[30*8-1:8] <= "Module Type: UDIMM";
|
|
uart_text[7:0] <= 8'h0a;
|
|
end
|
|
8'h03: begin
|
|
uart_start_send <= 1'b1;
|
|
uart_text_length <= 21;
|
|
uart_text[30*8-1:8] <= "Module Type: SO-DIMM";
|
|
uart_text[7:0] <= 8'h0a;
|
|
end
|
|
endcase
|
|
end
|
|
4: begin
|
|
uart_start_send <= 1'b1;
|
|
uart_text_length <= 29;
|
|
uart_text[30*8-1:8*20] <= "BA_BITS: ";
|
|
uart_text[8*20-1:8*19] <= hex_to_ascii(miso_data[6:4]+3);
|
|
uart_text[8*19-1:8*18] <= 8'h0a;
|
|
uart_text[8*18-1:8*2] <= "SDRAM_CAPACITY: ";
|
|
uart_text[8*2-1:8*1] <= hex_to_ascii(miso_data[3:0]);
|
|
uart_text[7:0] <= 8'h0a;
|
|
end
|
|
5: begin
|
|
uart_start_send <= 1'b1;
|
|
uart_text_length <= 26;
|
|
uart_text[30*8-1:8*16] <= "ROW_BITS: ";
|
|
case(miso_data[5:3])
|
|
0: uart_text[8*16-1:8*14] <= "12";
|
|
1: uart_text[8*16-1:8*14] <= "13";
|
|
2: uart_text[8*16-1:8*14] <= "14";
|
|
3: uart_text[8*16-1:8*14] <= "15";
|
|
4: uart_text[8*16-1:8*14] <= "16";
|
|
endcase
|
|
uart_text[8*14-1:8*13] <= 8'h0a;
|
|
uart_text[8*13-1:8*3] <= "COL_BITS: ";
|
|
case(miso_data[2:0])
|
|
0: uart_text[8*3-1:8*1] <= "9 ";
|
|
1: uart_text[8*3-1:8*1] <= "10";
|
|
2: uart_text[8*3-1:8*1] <= "11";
|
|
3: uart_text[8*3-1:8*1] <= "12";
|
|
endcase
|
|
uart_text[8*1-1:8*0] <= 8'h0a;
|
|
end
|
|
7: begin
|
|
uart_start_send <= 1'b1;
|
|
uart_text_length <= 18;
|
|
if(miso_data[5:3] == 1) begin
|
|
uart_text[30*8-1:8] <= "DUAL_RANK_DIMM: 1";
|
|
end
|
|
else begin
|
|
uart_text[30*8-1:8] <= "DUAL_RANK_DIMM: 0";
|
|
end
|
|
uart_text[7:0] <= 8'h0a;
|
|
end
|
|
8: begin
|
|
uart_start_send <= 1'b1;
|
|
uart_text_length <= 14;
|
|
case(miso_data[2:0])
|
|
0: uart_text[30*8-1:8] <= "BYTE_LANES: 1";
|
|
1: uart_text[30*8-1:8] <= "BYTE_LANES: 2";
|
|
2: uart_text[30*8-1:8] <= "BYTE_LANES: 4";
|
|
3: uart_text[30*8-1:8] <= "BYTE_LANES: 8";
|
|
endcase
|
|
uart_text[7:0] <= 8'h0a;
|
|
end
|
|
10: begin
|
|
mtb_dividend = miso_data;
|
|
uart_start_send <= 1'b1;
|
|
uart_text_length <= 30;
|
|
uart_text[30*8-1:8*1] <= "----- timing parameters -----";
|
|
uart_text[7:0] <= 8'h0a;
|
|
end
|
|
11: begin
|
|
mtb_divisor <= miso_data;
|
|
uart_start_send <= 1'b1;
|
|
uart_text_length <= 1;
|
|
uart_text[7:0] <= "m";
|
|
end
|
|
12: begin // give time for mtb to be computer
|
|
uart_start_send <= 1'b1;
|
|
uart_text_length <= 14;
|
|
uart_text[30*8-1:8*8] <= "tb: 0x";
|
|
uart_text[8*8-1:8*7] <= hex_to_ascii(mtb[7:4]);
|
|
uart_text[7*8-1:8*6] <= hex_to_ascii(mtb[3:0]);
|
|
uart_text[6*8-1:8*1] <= " (ps)";
|
|
uart_text[7:0] <= 8'h0a;
|
|
end
|
|
18: begin
|
|
uart_start_send <= 1'b1;
|
|
uart_text_length <= 17;
|
|
uart_text[30*8-1:8*3] <= "TRCD: mtb * 0x";
|
|
uart_text[3*8-1:8*2] <= hex_to_ascii(miso_data[7:4]);
|
|
uart_text[2*8-1:8*1] <= hex_to_ascii(miso_data[3:0]);
|
|
uart_text[7:0] <= 8'h0a;
|
|
end
|
|
20: begin
|
|
uart_start_send <= 1'b1;
|
|
uart_text_length <= 16;
|
|
uart_text[30*8-1:8*3] <= "TRP: mtb * 0x";
|
|
uart_text[3*8-1:8*2] <= hex_to_ascii(miso_data[7:4]);
|
|
uart_text[2*8-1:8*1] <= hex_to_ascii(miso_data[3:0]);
|
|
uart_text[7:0] <= 8'h0a;
|
|
end
|
|
21: begin
|
|
tras_high = miso_data[3:0];
|
|
uart_start_send <= 1'b1;
|
|
uart_text_length <= 1;
|
|
uart_text[7:0] <= "T";
|
|
end
|
|
22: begin
|
|
uart_start_send <= 1'b1;
|
|
uart_text_length <= 17;
|
|
uart_text[30*8-1:8*4] <= "RAS: mtb * 0x";
|
|
uart_text[4*8-1:8*3] <= hex_to_ascii(tras_high[3:0]);
|
|
uart_text[3*8-1:8*2] <= hex_to_ascii(miso_data[7:4]);
|
|
uart_text[2*8-1:8*1] <= hex_to_ascii(miso_data[3:0]);
|
|
uart_text[7:0] <= 8'h0a;
|
|
end
|
|
default: begin
|
|
skip_byte <= 1;
|
|
end
|
|
endcase
|
|
state_read_spd <= WAIT_UART_DONE;
|
|
end
|
|
WAIT_UART_DONE: if(uart_send_done || skip_byte) begin
|
|
state_read_spd <= READ_BYTE;
|
|
byte_address <= byte_address + 1;
|
|
if(byte_address == 63) begin
|
|
read_spd_done <= 1'b1;
|
|
state_read_spd <= IDLE;
|
|
end
|
|
skip_byte <= 1'b0;
|
|
end
|
|
else begin
|
|
uart_start_send <= 1'b0;
|
|
end
|
|
endcase
|
|
end
|
|
end
|
|
assign mtb = mtb_dividend*1000/mtb_divisor; // mtb is MCP (multicycle path) to give time for multiplication to be done
|
|
|
|
// FSM for uart
|
|
// uart_text = "Hello" , uart_text_length = 5
|
|
// [5<<3-1 (39):4<<3 (32)] = "H" , [4<<3-1 (31):3<<3(24)] = "e" , [3<<3-1(23):2<<3(16)] = "l" , [2<<3-1(15):1<<3(8)] = "l" , [1<<3-1(7):0<<3(0)] = "o"
|
|
always @(posedge i_clk, negedge i_rst_n) begin
|
|
if(!i_rst_n) begin
|
|
state_uart_send <= IDLE;
|
|
uart_text_length_index <= 0;
|
|
uart_tx_en <= 0;
|
|
uart_send_done <= 0;
|
|
uart_tx_data <= 0;
|
|
end
|
|
else begin
|
|
case(state_uart_send)
|
|
IDLE: if (uart_start_send) begin // if receive request to send via uart
|
|
state_uart_send <= SEND_BYTE;
|
|
uart_text_length_index <= uart_text_length-1;
|
|
end
|
|
else begin
|
|
uart_tx_en <= 1'b0;
|
|
uart_send_done <= 1'b0;
|
|
end
|
|
SEND_BYTE: if(!uart_tx_busy) begin // if uart tx is not busy, send character
|
|
uart_tx_en <= 1'b1;
|
|
uart_tx_data <= uart_text[((uart_text_length_index)<<3) +: 8];
|
|
end
|
|
else begin // once busy, go to wait state
|
|
state_uart_send <= WAIT_SEND;
|
|
uart_tx_en <= 1'b0;
|
|
end
|
|
WAIT_SEND: if(!uart_tx_busy) begin // if not busy again, then uart is done sending
|
|
if(uart_text_length_index != 0) begin // if not yet at 0, go to next character
|
|
uart_text_length_index <= uart_text_length_index - 1;
|
|
state_uart_send <= SEND_BYTE;
|
|
end
|
|
else begin // if already at 1, go back to idle
|
|
state_uart_send <= IDLE;
|
|
uart_send_done <= 1'b1;
|
|
end
|
|
end
|
|
default: state_uart_send <= IDLE;
|
|
endcase
|
|
end
|
|
end
|
|
|
|
// Function to convert hex to ASCII
|
|
function [7:0] hex_to_ascii;
|
|
input [3:0] hex;
|
|
begin
|
|
if (hex < 4'd10)
|
|
hex_to_ascii = hex + 8'd48; // ASCII for '0'-'9'
|
|
else
|
|
hex_to_ascii = hex + 8'd55; // ASCII for 'A'-'F'
|
|
end
|
|
endfunction
|
|
|
|
|
|
// module instantiations
|
|
i2c_master #(.DATA_WIDTH(8),.REGISTER_WIDTH(8),.ADDRESS_WIDTH(7))
|
|
i2c_master_inst(
|
|
.clock (i_clk),
|
|
.reset_n (i_rst_n),
|
|
.enable (enable),
|
|
.read_write (read_write),
|
|
.mosi_data (8'd0),
|
|
.register_address (register_address),
|
|
.device_address (device_address),
|
|
.divider (249), // 100MHz/(4*(249+1)) = 100KHz
|
|
|
|
.miso_data (miso_data),
|
|
.busy (busy),
|
|
|
|
.external_serial_data (i2c_sda),
|
|
.external_serial_clock (i2c_scl),
|
|
.slave_nack (slave_nack)
|
|
);
|
|
|
|
uart_tx #(
|
|
.BIT_RATE(115200),
|
|
.CLK_HZ(100_000_000),
|
|
.PAYLOAD_BITS(8),
|
|
.STOP_BITS(1)
|
|
) uart_tx_inst (
|
|
.clk(i_clk), // Top level system clock input
|
|
.resetn(i_rst_n), // Asynchronous active low reset.
|
|
.uart_txd(uart_tx) , // UART transmit pin.
|
|
.uart_tx_busy(uart_tx_busy), // Module busy sending previous item.
|
|
.uart_tx_en(uart_tx_en), // Send the data on uart_tx_data
|
|
.uart_tx_data(uart_tx_data) // The data to be sent
|
|
);
|
|
|
|
generate
|
|
if(1) begin // set to 1 to debug registers in ILA
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_0;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_1;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_2;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_3;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_4;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_5;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_6;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_7;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_8;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_9;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_10;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_11;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_12;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_13;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_14;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_15;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_16;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_17;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_18;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_19;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_20;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_21;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_22;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_23;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_24;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_25;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_26;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_27;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_28;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_29;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_30;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_31;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_32;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_33;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_34;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_35;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_36;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_37;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_38;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_39;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_40;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_41;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_42;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_43;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_44;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_45;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_46;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_47;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_48;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_49;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_50;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_51;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_52;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_53;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_54;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_55;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_56;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_57;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_58;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_59;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_60;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_61;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_62;
|
|
(* mark_debug = "true" *) wire [7:0] byte_data_63;
|
|
|
|
// Assign each wire to its respective array index
|
|
assign byte_data_0 = byte_data[0];
|
|
assign byte_data_1 = byte_data[1];
|
|
assign byte_data_2 = byte_data[2];
|
|
assign byte_data_3 = byte_data[3];
|
|
assign byte_data_4 = byte_data[4];
|
|
assign byte_data_5 = byte_data[5];
|
|
assign byte_data_6 = byte_data[6];
|
|
assign byte_data_7 = byte_data[7];
|
|
assign byte_data_8 = byte_data[8];
|
|
assign byte_data_9 = byte_data[9];
|
|
assign byte_data_10 = byte_data[10];
|
|
assign byte_data_11 = byte_data[11];
|
|
assign byte_data_12 = byte_data[12];
|
|
assign byte_data_13 = byte_data[13];
|
|
assign byte_data_14 = byte_data[14];
|
|
assign byte_data_15 = byte_data[15];
|
|
assign byte_data_16 = byte_data[16];
|
|
assign byte_data_17 = byte_data[17];
|
|
assign byte_data_18 = byte_data[18];
|
|
assign byte_data_19 = byte_data[19];
|
|
assign byte_data_20 = byte_data[20];
|
|
assign byte_data_21 = byte_data[21];
|
|
assign byte_data_22 = byte_data[22];
|
|
assign byte_data_23 = byte_data[23];
|
|
assign byte_data_24 = byte_data[24];
|
|
assign byte_data_25 = byte_data[25];
|
|
assign byte_data_26 = byte_data[26];
|
|
assign byte_data_27 = byte_data[27];
|
|
assign byte_data_28 = byte_data[28];
|
|
assign byte_data_29 = byte_data[29];
|
|
assign byte_data_30 = byte_data[30];
|
|
assign byte_data_31 = byte_data[31];
|
|
assign byte_data_32 = byte_data[32];
|
|
assign byte_data_33 = byte_data[33];
|
|
assign byte_data_34 = byte_data[34];
|
|
assign byte_data_35 = byte_data[35];
|
|
assign byte_data_36 = byte_data[36];
|
|
assign byte_data_37 = byte_data[37];
|
|
assign byte_data_38 = byte_data[38];
|
|
assign byte_data_39 = byte_data[39];
|
|
assign byte_data_40 = byte_data[40];
|
|
assign byte_data_41 = byte_data[41];
|
|
assign byte_data_42 = byte_data[42];
|
|
assign byte_data_43 = byte_data[43];
|
|
assign byte_data_44 = byte_data[44];
|
|
assign byte_data_45 = byte_data[45];
|
|
assign byte_data_46 = byte_data[46];
|
|
assign byte_data_47 = byte_data[47];
|
|
assign byte_data_48 = byte_data[48];
|
|
assign byte_data_49 = byte_data[49];
|
|
assign byte_data_50 = byte_data[50];
|
|
assign byte_data_51 = byte_data[51];
|
|
assign byte_data_52 = byte_data[52];
|
|
assign byte_data_53 = byte_data[53];
|
|
assign byte_data_54 = byte_data[54];
|
|
assign byte_data_55 = byte_data[55];
|
|
assign byte_data_56 = byte_data[56];
|
|
assign byte_data_57 = byte_data[57];
|
|
assign byte_data_58 = byte_data[58];
|
|
assign byte_data_59 = byte_data[59];
|
|
assign byte_data_60 = byte_data[60];
|
|
assign byte_data_61 = byte_data[61];
|
|
assign byte_data_62 = byte_data[62];
|
|
assign byte_data_63 = byte_data[63];
|
|
end
|
|
endgenerate
|
|
endmodule
|
|
|
|
|