`include "minsoc_bench_defines.v"
|
`include "minsoc_bench_defines.v"
|
`include "minsoc_defines.v"
|
`include "minsoc_defines.v"
|
|
|
module minsoc_bench();
|
module minsoc_bench();
|
|
|
reg clock, reset;
|
reg clock, reset;
|
|
|
wire dbg_tms_i;
|
wire dbg_tms_i;
|
wire dbg_tck_i;
|
wire dbg_tck_i;
|
wire dbg_tdi_i;
|
wire dbg_tdi_i;
|
wire dbg_tdo_o;
|
wire dbg_tdo_o;
|
wire jtag_vref;
|
wire jtag_vref;
|
wire jtag_gnd;
|
wire jtag_gnd;
|
|
|
wire spi_mosi;
|
wire spi_mosi;
|
reg spi_miso;
|
reg spi_miso;
|
wire spi_sclk;
|
wire spi_sclk;
|
wire [1:0] spi_ss;
|
wire [1:0] spi_ss;
|
|
|
wire uart_stx;
|
wire uart_stx;
|
wire uart_srx;
|
reg uart_srx;
|
|
|
wire eth_col;
|
wire eth_col;
|
wire eth_crs;
|
wire eth_crs;
|
wire eth_trst;
|
wire eth_trst;
|
wire eth_tx_clk;
|
wire eth_tx_clk;
|
wire eth_tx_en;
|
wire eth_tx_en;
|
wire eth_tx_er;
|
wire eth_tx_er;
|
wire [3:0] eth_txd;
|
wire [3:0] eth_txd;
|
wire eth_rx_clk;
|
wire eth_rx_clk;
|
wire eth_rx_dv;
|
wire eth_rx_dv;
|
wire eth_rx_er;
|
wire eth_rx_er;
|
wire [3:0] eth_rxd;
|
wire [3:0] eth_rxd;
|
wire eth_fds_mdint;
|
wire eth_fds_mdint;
|
wire eth_mdc;
|
wire eth_mdc;
|
wire eth_mdio;
|
wire eth_mdio;
|
|
|
//
|
//
|
// TASKS registers to communicate with interfaces
|
// TASKS registers to communicate with interfaces
|
//
|
//
|
reg [7:0] tx_data [0:1518]; //receive buffer
|
reg [7:0] tx_data [0:1518]; //receive buffer
|
reg [31:0] data_in [1023:0]; //send buffer
|
reg [31:0] data_in [1023:0]; //send buffer
|
|
|
|
|
//
|
//
|
// Testbench mechanics
|
// Testbench mechanics
|
//
|
//
|
reg [7:0] program_mem[(1<<(`MEMORY_ADR_WIDTH+2))-1:0];
|
reg [7:0] program_mem[(1<<(`MEMORY_ADR_WIDTH+2))-1:0];
|
integer initialize, final, ptr;
|
integer initialize, final, ptr;
|
reg [8*64:0] file_name;
|
reg [8*64:0] file_name;
|
reg load_file;
|
reg load_file;
|
|
|
initial begin
|
initial begin
|
reset = 1'b0;
|
reset = 1'b0;
|
clock = 1'b0;
|
clock = 1'b0;
|
|
|
load_file = 1'b0;
|
load_file = 1'b0;
|
`ifdef INITIALIZE_MEMORY_MODEL
|
`ifdef INITIALIZE_MEMORY_MODEL
|
load_file = 1'b1;
|
load_file = 1'b1;
|
`endif
|
`endif
|
`ifdef START_UP
|
`ifdef START_UP
|
load_file = 1'b1;
|
load_file = 1'b1;
|
`endif
|
`endif
|
|
|
//get firmware hex file from command line input
|
//get firmware hex file from command line input
|
if ( load_file ) begin
|
if ( load_file ) begin
|
if ( ! $value$plusargs("file_name=%s", file_name) || file_name == 0 ) begin
|
if ( ! $value$plusargs("file_name=%s", file_name) || file_name == 0 ) begin
|
$display("ERROR: please specify an input file to start.");
|
$display("ERROR: please specify an input file to start.");
|
$finish;
|
$finish;
|
end
|
end
|
$readmemh(file_name, program_mem);
|
$readmemh(file_name, program_mem);
|
// First word comprehends size of program
|
// First word comprehends size of program
|
final = { program_mem[0] , program_mem[1] , program_mem[2] , program_mem[3] };
|
final = { program_mem[0] , program_mem[1] , program_mem[2] , program_mem[3] };
|
end
|
end
|
|
|
`ifdef INITIALIZE_MEMORY_MODEL
|
`ifdef INITIALIZE_MEMORY_MODEL
|
// Initialize memory with firmware
|
// Initialize memory with firmware
|
initialize = 0;
|
initialize = 0;
|
while ( initialize < final ) begin
|
while ( initialize < final ) begin
|
minsoc_top_0.onchip_ram_top.block_ram_3.mem[initialize/4] = program_mem[initialize];
|
minsoc_top_0.onchip_ram_top.block_ram_3.mem[initialize/4] = program_mem[initialize];
|
minsoc_top_0.onchip_ram_top.block_ram_2.mem[initialize/4] = program_mem[initialize+1];
|
minsoc_top_0.onchip_ram_top.block_ram_2.mem[initialize/4] = program_mem[initialize+1];
|
minsoc_top_0.onchip_ram_top.block_ram_1.mem[initialize/4] = program_mem[initialize+2];
|
minsoc_top_0.onchip_ram_top.block_ram_1.mem[initialize/4] = program_mem[initialize+2];
|
minsoc_top_0.onchip_ram_top.block_ram_0.mem[initialize/4] = program_mem[initialize+3];
|
minsoc_top_0.onchip_ram_top.block_ram_0.mem[initialize/4] = program_mem[initialize+3];
|
initialize = initialize + 4;
|
initialize = initialize + 4;
|
end
|
end
|
$display("Memory model initialized with firmware:");
|
$display("Memory model initialized with firmware:");
|
$display("%s", file_name);
|
$display("%s", file_name);
|
$display("%d Bytes loaded from %d ...", initialize , final);
|
$display("%d Bytes loaded from %d ...", initialize , final);
|
`endif
|
`endif
|
|
|
// Reset controller
|
// Reset controller
|
repeat (2) @ (negedge clock);
|
repeat (2) @ (negedge clock);
|
reset = 1'b1;
|
reset = 1'b1;
|
repeat (16) @ (negedge clock);
|
repeat (16) @ (negedge clock);
|
reset = 1'b0;
|
reset = 1'b0;
|
|
|
`ifdef START_UP
|
`ifdef START_UP
|
// Pass firmware over spi to or1k_startup
|
// Pass firmware over spi to or1k_startup
|
ptr = 0;
|
ptr = 0;
|
//read dummy
|
//read dummy
|
send_spi(program_mem[ptr]);
|
send_spi(program_mem[ptr]);
|
send_spi(program_mem[ptr]);
|
send_spi(program_mem[ptr]);
|
send_spi(program_mem[ptr]);
|
send_spi(program_mem[ptr]);
|
send_spi(program_mem[ptr]);
|
send_spi(program_mem[ptr]);
|
//~read dummy
|
//~read dummy
|
while ( ptr < final ) begin
|
while ( ptr < final ) begin
|
send_spi(program_mem[ptr]);
|
send_spi(program_mem[ptr]);
|
ptr = ptr + 1;
|
ptr = ptr + 1;
|
end
|
end
|
$display("Memory start-up completed...");
|
$display("Memory start-up completed...");
|
$display("Loaded firmware:");
|
$display("Loaded firmware:");
|
$display("%s", file_name);
|
$display("%s", file_name);
|
`endif
|
`endif
|
//
|
//
|
// Testbench START
|
// Testbench START
|
//
|
//
|
|
|
|
|
end
|
end
|
|
|
|
|
//
|
//
|
// Modules instantiations
|
// Modules instantiations
|
//
|
//
|
minsoc_top minsoc_top_0(
|
minsoc_top minsoc_top_0(
|
.clk(clock),
|
.clk(clock),
|
.reset(reset)
|
.reset(reset)
|
|
|
//JTAG ports
|
//JTAG ports
|
`ifdef GENERIC_TAP
|
`ifdef GENERIC_TAP
|
, .jtag_tdi(dbg_tdi_i),
|
, .jtag_tdi(dbg_tdi_i),
|
.jtag_tms(dbg_tms_i),
|
.jtag_tms(dbg_tms_i),
|
.jtag_tck(dbg_tck_i),
|
.jtag_tck(dbg_tck_i),
|
.jtag_tdo(dbg_tdo_o),
|
.jtag_tdo(dbg_tdo_o),
|
.jtag_vref(jtag_vref),
|
.jtag_vref(jtag_vref),
|
.jtag_gnd(jtag_gnd)
|
.jtag_gnd(jtag_gnd)
|
`endif
|
`endif
|
|
|
//SPI ports
|
//SPI ports
|
`ifdef START_UP
|
`ifdef START_UP
|
, .spi_flash_mosi(spi_mosi),
|
, .spi_flash_mosi(spi_mosi),
|
.spi_flash_miso(spi_miso),
|
.spi_flash_miso(spi_miso),
|
.spi_flash_sclk(spi_sclk),
|
.spi_flash_sclk(spi_sclk),
|
.spi_flash_ss(spi_ss)
|
.spi_flash_ss(spi_ss)
|
`endif
|
`endif
|
|
|
//UART ports
|
//UART ports
|
`ifdef UART
|
`ifdef UART
|
, .uart_stx(uart_stx),
|
, .uart_stx(uart_stx),
|
.uart_srx(uart_srx)
|
.uart_srx(uart_srx)
|
`endif // !UART
|
`endif // !UART
|
|
|
// Ethernet ports
|
// Ethernet ports
|
`ifdef ETHERNET
|
`ifdef ETHERNET
|
, .eth_col(eth_col),
|
, .eth_col(eth_col),
|
.eth_crs(eth_crs),
|
.eth_crs(eth_crs),
|
.eth_trste(eth_trst),
|
.eth_trste(eth_trst),
|
.eth_tx_clk(eth_tx_clk),
|
.eth_tx_clk(eth_tx_clk),
|
.eth_tx_en(eth_tx_en),
|
.eth_tx_en(eth_tx_en),
|
.eth_tx_er(eth_tx_er),
|
.eth_tx_er(eth_tx_er),
|
.eth_txd(eth_txd),
|
.eth_txd(eth_txd),
|
.eth_rx_clk(eth_rx_clk),
|
.eth_rx_clk(eth_rx_clk),
|
.eth_rx_dv(eth_rx_dv),
|
.eth_rx_dv(eth_rx_dv),
|
.eth_rx_er(eth_rx_er),
|
.eth_rx_er(eth_rx_er),
|
.eth_rxd(eth_rxd),
|
.eth_rxd(eth_rxd),
|
.eth_fds_mdint(eth_fds_mdint),
|
.eth_fds_mdint(eth_fds_mdint),
|
.eth_mdc(eth_mdc),
|
.eth_mdc(eth_mdc),
|
.eth_mdio(eth_mdio)
|
.eth_mdio(eth_mdio)
|
`endif // !ETHERNET
|
`endif // !ETHERNET
|
);
|
);
|
|
|
`ifdef VPI_DEBUG
|
`ifdef VPI_DEBUG
|
dbg_comm_vpi dbg_if(
|
dbg_comm_vpi dbg_if(
|
.SYS_CLK(clock),
|
.SYS_CLK(clock),
|
.P_TMS(dbg_tms_i),
|
.P_TMS(dbg_tms_i),
|
.P_TCK(dbg_tck_i),
|
.P_TCK(dbg_tck_i),
|
.P_TRST(),
|
.P_TRST(),
|
.P_TDI(dbg_tdi_i),
|
.P_TDI(dbg_tdi_i),
|
.P_TDO(dbg_tdo_o)
|
.P_TDO(dbg_tdo_o)
|
);
|
);
|
`else
|
`else
|
assign dbg_tdi_i = 1;
|
assign dbg_tdi_i = 1;
|
assign dbg_tck_i = 0;
|
assign dbg_tck_i = 0;
|
assign dbg_tms_i = 1;
|
assign dbg_tms_i = 1;
|
`endif
|
`endif
|
|
|
`ifdef ETHERNET
|
`ifdef ETHERNET
|
eth_phy my_phy // This PHY model simulate simplified Intel LXT971A PHY
|
eth_phy my_phy // This PHY model simulate simplified Intel LXT971A PHY
|
(
|
(
|
// COMMON
|
// COMMON
|
.m_rst_n_i(1'b1),
|
.m_rst_n_i(1'b1),
|
|
|
// MAC TX
|
// MAC TX
|
.mtx_clk_o(eth_tx_clk),
|
.mtx_clk_o(eth_tx_clk),
|
.mtxd_i(eth_txd),
|
.mtxd_i(eth_txd),
|
.mtxen_i(eth_tx_en),
|
.mtxen_i(eth_tx_en),
|
.mtxerr_i(eth_tx_er),
|
.mtxerr_i(eth_tx_er),
|
|
|
// MAC RX
|
// MAC RX
|
.mrx_clk_o(eth_rx_clk),
|
.mrx_clk_o(eth_rx_clk),
|
.mrxd_o(eth_rxd),
|
.mrxd_o(eth_rxd),
|
.mrxdv_o(eth_rx_dv),
|
.mrxdv_o(eth_rx_dv),
|
.mrxerr_o(eth_rx_er),
|
.mrxerr_o(eth_rx_er),
|
|
|
.mcoll_o(eth_col),
|
.mcoll_o(eth_col),
|
.mcrs_o(eth_crs),
|
.mcrs_o(eth_crs),
|
|
|
// MIIM
|
// MIIM
|
.mdc_i(eth_mdc),
|
.mdc_i(eth_mdc),
|
.md_io(eth_mdio),
|
.md_io(eth_mdio),
|
|
|
// SYSTEM
|
// SYSTEM
|
.phy_log()
|
.phy_log()
|
);
|
);
|
`endif // !ETHERNET
|
`endif // !ETHERNET
|
|
|
|
|
//
|
//
|
// Regular clocking and output
|
// Regular clocking and output
|
//
|
//
|
always begin
|
always begin
|
#((`CLK_PERIOD)/2) clock <= ~clock;
|
#((`CLK_PERIOD)/2) clock <= ~clock;
|
end
|
end
|
|
|
`ifdef VCD_OUTPUT
|
`ifdef VCD_OUTPUT
|
initial begin
|
initial begin
|
$dumpfile("../results/minsoc_wave.vcd");
|
$dumpfile("../results/minsoc_wave.vcd");
|
$dumpvars();
|
$dumpvars();
|
end
|
end
|
`endif
|
`endif
|
|
|
|
|
//
|
//
|
// Functionalities tasks: SPI Startup and UART Monitor
|
// Functionalities tasks: SPI Startup and UART Monitor
|
//
|
//
|
//SPI START_UP
|
//SPI START_UP
|
`ifdef START_UP
|
`ifdef START_UP
|
task send_spi;
|
task send_spi;
|
input [7:0] data_in;
|
input [7:0] data_in;
|
integer i;
|
integer i;
|
begin
|
begin
|
i = 7;
|
i = 7;
|
for ( i = 7 ; i >= 0; i = i - 1 ) begin
|
for ( i = 7 ; i >= 0; i = i - 1 ) begin
|
spi_miso = data_in[i];
|
spi_miso = data_in[i];
|
@ (posedge spi_sclk);
|
@ (posedge spi_sclk);
|
end
|
end
|
end
|
end
|
endtask
|
endtask
|
`endif
|
`endif
|
//~SPI START_UP
|
//~SPI START_UP
|
|
|
//UART Monitor (prints uart output on the terminal)
|
//UART Monitor (prints uart output on the terminal)
|
`ifdef UART
|
`ifdef UART
|
parameter UART_TX_WAIT = (`FREQ / `UART_BAUDRATE) * `CLK_PERIOD;
|
parameter UART_TX_WAIT = (`FREQ / `UART_BAUDRATE) * `CLK_PERIOD;
|
|
|
// Something to trigger the task
|
// Something to trigger the task
|
always @(posedge clock)
|
always @(posedge clock)
|
uart_decoder;
|
uart_decoder;
|
|
|
task uart_decoder;
|
task uart_decoder;
|
integer i;
|
integer i;
|
reg [7:0] tx_byte;
|
reg [7:0] tx_byte;
|
begin
|
begin
|
|
|
// Wait for start bit
|
// Wait for start bit
|
while (uart_stx == 1'b1)
|
while (uart_stx == 1'b1)
|
@(uart_stx);
|
@(uart_stx);
|
|
|
#(UART_TX_WAIT+(UART_TX_WAIT/2));
|
#(UART_TX_WAIT+(UART_TX_WAIT/2));
|
|
|
for ( i = 0; i < 8 ; i = i + 1 ) begin
|
for ( i = 0; i < 8 ; i = i + 1 ) begin
|
tx_byte[i] = uart_stx;
|
tx_byte[i] = uart_stx;
|
#UART_TX_WAIT;
|
#UART_TX_WAIT;
|
end
|
end
|
|
|
//Check for stop bit
|
//Check for stop bit
|
if (uart_stx == 1'b0) begin
|
if (uart_stx == 1'b0) begin
|
//$display("* WARNING: user stop bit not received when expected at time %d__", $time);
|
//$display("* WARNING: user stop bit not received when expected at time %d__", $time);
|
// Wait for return to idle
|
// Wait for return to idle
|
while (uart_stx == 1'b0)
|
while (uart_stx == 1'b0)
|
@(uart_stx);
|
@(uart_stx);
|
//$display("* USER UART returned to idle at time %d",$time);
|
//$display("* USER UART returned to idle at time %d",$time);
|
end
|
end
|
// display the char
|
// display the char
|
$write("%c", tx_byte);
|
$write("%c", tx_byte);
|
end
|
end
|
endtask
|
endtask
|
`endif // !UART
|
`endif // !UART
|
//~UART Monitor
|
//~UART Monitor
|
|
|
|
|
//
|
//
|
// TASKS to communicate with interfaces
|
// TASKS to communicate with interfaces
|
//
|
//
|
//MAC_DATA
|
//MAC_DATA
|
//
|
//
|
`ifdef ETHERNET
|
`ifdef ETHERNET
|
reg [31:0] crc32_result;
|
reg [31:0] crc32_result;
|
|
|
task get_mac;
|
task get_mac;
|
integer conta;
|
integer conta;
|
reg LSB;
|
reg LSB;
|
begin
|
begin
|
conta = 0;
|
conta = 0;
|
LSB = 1;
|
LSB = 1;
|
@ ( posedge eth_tx_en);
|
@ ( posedge eth_tx_en);
|
while ( eth_tx_en == 1'b1 ) begin
|
while ( eth_tx_en == 1'b1 ) begin
|
@ (negedge eth_tx_clk) begin
|
@ (negedge eth_tx_clk) begin
|
if ( LSB == 1'b1 )
|
if ( LSB == 1'b1 )
|
tx_data[conta][3:0] = eth_txd;
|
tx_data[conta][3:0] = eth_txd;
|
else begin
|
else begin
|
tx_data[conta][7:4] = eth_txd;
|
tx_data[conta][7:4] = eth_txd;
|
conta = conta + 1;
|
conta = conta + 1;
|
end
|
end
|
LSB = ~LSB;
|
LSB = ~LSB;
|
end
|
end
|
end
|
end
|
end
|
end
|
endtask
|
endtask
|
|
|
task send_mac;
|
task send_mac;
|
input [11:0] command;
|
input [11:0] command;
|
input [31:0] param1;
|
input [31:0] param1;
|
input [31:0] param2;
|
input [31:0] param2;
|
input [223:0] data;
|
input [223:0] data;
|
|
|
integer conta;
|
integer conta;
|
|
|
begin
|
begin
|
//DEST MAC
|
//DEST MAC
|
my_phy.rx_mem[0] = 8'h55;
|
my_phy.rx_mem[0] = 8'h55;
|
my_phy.rx_mem[1] = 8'h47;
|
my_phy.rx_mem[1] = 8'h47;
|
my_phy.rx_mem[2] = 8'h34;
|
my_phy.rx_mem[2] = 8'h34;
|
my_phy.rx_mem[3] = 8'h22;
|
my_phy.rx_mem[3] = 8'h22;
|
my_phy.rx_mem[4] = 8'h88;
|
my_phy.rx_mem[4] = 8'h88;
|
my_phy.rx_mem[5] = 8'h92;
|
my_phy.rx_mem[5] = 8'h92;
|
|
|
//SOURCE MAC
|
//SOURCE MAC
|
my_phy.rx_mem[6] = 8'h00;
|
my_phy.rx_mem[6] = 8'h00;
|
my_phy.rx_mem[7] = 8'h00;
|
my_phy.rx_mem[7] = 8'h00;
|
my_phy.rx_mem[8] = 8'hC0;
|
my_phy.rx_mem[8] = 8'hC0;
|
my_phy.rx_mem[9] = 8'h41;
|
my_phy.rx_mem[9] = 8'h41;
|
my_phy.rx_mem[10] = 8'h36;
|
my_phy.rx_mem[10] = 8'h36;
|
my_phy.rx_mem[11] = 8'hD3;
|
my_phy.rx_mem[11] = 8'hD3;
|
|
|
//LEN
|
//LEN
|
my_phy.rx_mem[12] = 8'h00;
|
my_phy.rx_mem[12] = 8'h00;
|
my_phy.rx_mem[13] = 8'h04;
|
my_phy.rx_mem[13] = 8'h04;
|
|
|
//DATA
|
//DATA
|
my_phy.rx_mem[14] = 8'hFF;
|
my_phy.rx_mem[14] = 8'hFF;
|
my_phy.rx_mem[15] = 8'hFA;
|
my_phy.rx_mem[15] = 8'hFA;
|
my_phy.rx_mem[16] = command[11:4];
|
my_phy.rx_mem[16] = command[11:4];
|
my_phy.rx_mem[17] = { command[3:0] , 4'h7 };
|
my_phy.rx_mem[17] = { command[3:0] , 4'h7 };
|
|
|
my_phy.rx_mem[18] = 8'hAA;
|
my_phy.rx_mem[18] = 8'hAA;
|
my_phy.rx_mem[19] = 8'hAA;
|
my_phy.rx_mem[19] = 8'hAA;
|
|
|
//parameter 1
|
//parameter 1
|
my_phy.rx_mem[20] = param1[31:24];
|
my_phy.rx_mem[20] = param1[31:24];
|
my_phy.rx_mem[21] = param1[23:16];
|
my_phy.rx_mem[21] = param1[23:16];
|
my_phy.rx_mem[22] = param1[15:8];
|
my_phy.rx_mem[22] = param1[15:8];
|
my_phy.rx_mem[23] = param1[7:0];
|
my_phy.rx_mem[23] = param1[7:0];
|
|
|
//parameter 2
|
//parameter 2
|
my_phy.rx_mem[24] = param2[31:24];
|
my_phy.rx_mem[24] = param2[31:24];
|
my_phy.rx_mem[25] = param2[23:16];
|
my_phy.rx_mem[25] = param2[23:16];
|
my_phy.rx_mem[26] = param2[15:8];
|
my_phy.rx_mem[26] = param2[15:8];
|
my_phy.rx_mem[27] = param2[7:0];
|
my_phy.rx_mem[27] = param2[7:0];
|
|
|
//data
|
//data
|
my_phy.rx_mem[28] = data[223:216];
|
my_phy.rx_mem[28] = data[223:216];
|
my_phy.rx_mem[29] = data[215:208];
|
my_phy.rx_mem[29] = data[215:208];
|
my_phy.rx_mem[30] = data[207:200];
|
my_phy.rx_mem[30] = data[207:200];
|
my_phy.rx_mem[31] = data[199:192];
|
my_phy.rx_mem[31] = data[199:192];
|
my_phy.rx_mem[32] = data[191:184];
|
my_phy.rx_mem[32] = data[191:184];
|
my_phy.rx_mem[33] = data[183:176];
|
my_phy.rx_mem[33] = data[183:176];
|
my_phy.rx_mem[34] = data[175:168];
|
my_phy.rx_mem[34] = data[175:168];
|
my_phy.rx_mem[35] = data[167:160];
|
my_phy.rx_mem[35] = data[167:160];
|
my_phy.rx_mem[36] = data[159:152];
|
my_phy.rx_mem[36] = data[159:152];
|
my_phy.rx_mem[37] = data[151:144];
|
my_phy.rx_mem[37] = data[151:144];
|
my_phy.rx_mem[38] = data[143:136];
|
my_phy.rx_mem[38] = data[143:136];
|
my_phy.rx_mem[39] = data[135:128];
|
my_phy.rx_mem[39] = data[135:128];
|
my_phy.rx_mem[40] = data[127:120];
|
my_phy.rx_mem[40] = data[127:120];
|
my_phy.rx_mem[41] = data[119:112];
|
my_phy.rx_mem[41] = data[119:112];
|
my_phy.rx_mem[42] = data[111:104];
|
my_phy.rx_mem[42] = data[111:104];
|
my_phy.rx_mem[43] = data[103:96];
|
my_phy.rx_mem[43] = data[103:96];
|
my_phy.rx_mem[44] = data[95:88];
|
my_phy.rx_mem[44] = data[95:88];
|
my_phy.rx_mem[45] = data[87:80];
|
my_phy.rx_mem[45] = data[87:80];
|
my_phy.rx_mem[46] = data[79:72];
|
my_phy.rx_mem[46] = data[79:72];
|
my_phy.rx_mem[47] = data[71:64];
|
my_phy.rx_mem[47] = data[71:64];
|
my_phy.rx_mem[48] = data[63:56];
|
my_phy.rx_mem[48] = data[63:56];
|
my_phy.rx_mem[49] = data[55:48];
|
my_phy.rx_mem[49] = data[55:48];
|
my_phy.rx_mem[50] = data[47:40];
|
my_phy.rx_mem[50] = data[47:40];
|
my_phy.rx_mem[51] = data[39:32];
|
my_phy.rx_mem[51] = data[39:32];
|
my_phy.rx_mem[52] = data[31:24];
|
my_phy.rx_mem[52] = data[31:24];
|
my_phy.rx_mem[53] = data[23:16];
|
my_phy.rx_mem[53] = data[23:16];
|
my_phy.rx_mem[54] = data[15:8];
|
my_phy.rx_mem[54] = data[15:8];
|
my_phy.rx_mem[55] = data[7:0];
|
my_phy.rx_mem[55] = data[7:0];
|
|
|
//PAD
|
//PAD
|
for ( conta = 56; conta < 60; conta = conta + 1 ) begin
|
for ( conta = 56; conta < 60; conta = conta + 1 ) begin
|
my_phy.rx_mem[conta] = 8'h00;
|
my_phy.rx_mem[conta] = 8'h00;
|
end
|
end
|
|
|
gencrc32;
|
gencrc32;
|
|
|
my_phy.rx_mem[60] = crc32_result[31:24];
|
my_phy.rx_mem[60] = crc32_result[31:24];
|
my_phy.rx_mem[61] = crc32_result[23:16];
|
my_phy.rx_mem[61] = crc32_result[23:16];
|
my_phy.rx_mem[62] = crc32_result[15:8];
|
my_phy.rx_mem[62] = crc32_result[15:8];
|
my_phy.rx_mem[63] = crc32_result[7:0];
|
my_phy.rx_mem[63] = crc32_result[7:0];
|
|
|
my_phy.send_rx_packet( 64'h0055_5555_5555_5555, 4'h7, 8'hD5, 32'h0000_0000, 32'h0000_0040, 1'b0 );
|
my_phy.send_rx_packet( 64'h0055_5555_5555_5555, 4'h7, 8'hD5, 32'h0000_0000, 32'h0000_0040, 1'b0 );
|
end
|
end
|
|
|
endtask
|
endtask
|
|
|
//CRC32
|
//CRC32
|
parameter [31:0] CRC32_POLY = 32'h04C11DB7;
|
parameter [31:0] CRC32_POLY = 32'h04C11DB7;
|
|
|
task gencrc32;
|
task gencrc32;
|
integer byte, bit;
|
integer byte, bit;
|
reg msb;
|
reg msb;
|
reg [7:0] current_byte;
|
reg [7:0] current_byte;
|
reg [31:0] temp;
|
reg [31:0] temp;
|
|
|
integer crc32_length;
|
integer crc32_length;
|
|
|
begin
|
begin
|
crc32_length = 60;
|
crc32_length = 60;
|
crc32_result = 32'hffffffff;
|
crc32_result = 32'hffffffff;
|
for (byte = 0; byte < crc32_length; byte = byte + 1) begin
|
for (byte = 0; byte < crc32_length; byte = byte + 1) begin
|
current_byte = my_phy.rx_mem[byte];
|
current_byte = my_phy.rx_mem[byte];
|
for (bit = 0; bit < 8; bit = bit + 1) begin
|
for (bit = 0; bit < 8; bit = bit + 1) begin
|
msb = crc32_result[31];
|
msb = crc32_result[31];
|
crc32_result = crc32_result << 1;
|
crc32_result = crc32_result << 1;
|
if (msb != current_byte[bit]) begin
|
if (msb != current_byte[bit]) begin
|
crc32_result = crc32_result ^ CRC32_POLY;
|
crc32_result = crc32_result ^ CRC32_POLY;
|
crc32_result[0] = 1;
|
crc32_result[0] = 1;
|
end
|
end
|
end
|
end
|
end
|
end
|
|
|
// Last step is to "mirror" every bit, swap the 4 bytes, and then complement each bit.
|
// Last step is to "mirror" every bit, swap the 4 bytes, and then complement each bit.
|
//
|
//
|
// Mirror:
|
// Mirror:
|
for (bit = 0; bit < 32; bit = bit + 1)
|
for (bit = 0; bit < 32; bit = bit + 1)
|
temp[31-bit] = crc32_result[bit];
|
temp[31-bit] = crc32_result[bit];
|
|
|
// Swap and Complement:
|
// Swap and Complement:
|
crc32_result = ~{temp[7:0], temp[15:8], temp[23:16], temp[31:24]};
|
crc32_result = ~{temp[7:0], temp[15:8], temp[23:16], temp[31:24]};
|
end
|
end
|
endtask
|
endtask
|
//~CRC32
|
//~CRC32
|
`endif // !ETHERNET
|
`endif // !ETHERNET
|
//~MAC_DATA
|
//~MAC_DATA
|
|
|
|
|
endmodule
|
endmodule
|
|
|
|
|