Skip to content

Commit

Permalink
Testbench for SPI write
Browse files Browse the repository at this point in the history
  • Loading branch information
IveanEx committed Oct 7, 2024
1 parent 88a1c1c commit 384af30
Show file tree
Hide file tree
Showing 2 changed files with 127 additions and 8 deletions.
120 changes: 118 additions & 2 deletions target/rtl/test/spi_tb.sv
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
`define SEEK_SET 0
`define SEEK_CUR 1
`define SEEK_END 2

task automatic spi_read(input logic [31:0] addr, input integer length);
// Inputs:
// addr - 32-bit Address to read from
Expand Down Expand Up @@ -27,10 +31,10 @@ task automatic spi_read(input logic [31:0] addr, input integer length);
end

@(posedge spis_sck_i);
spis_csb_i = 1; // Bring CSB high to end the transaction
spis_csb_i = 1; // Bring CSB high to end the transaction
#1us; // Wait for a clock edge to align
@(posedge spis_sck_i);
spis_csb_i = 0; // Bring CSB high to end the transaction
spis_csb_i = 0; // Bring CSB high to end the transaction

// Set the SPI Read MEM code
cmd = 8'hB;
Expand Down Expand Up @@ -91,3 +95,115 @@ task automatic spi_read(input logic [31:0] addr, input integer length);
@(negedge spis_sck_i);
spis_csb_i = 1;
endtask


task automatic spi_write(input string path, input logic [31:0] addr);
// Inputs:
// path - Path to the file to write
// addr - 32-bit Address to read from

reg [7:0] cmd; // SPI write command code
integer i, j;
reg [3:0] mosi_data; // Data to send over SPI (master out)
reg [3:0] miso_data; // Data received from SPI (slave out)
integer file;
integer file_size;

// Wait for a clock edge to align
@(posedge spis_sck_i);
spis_csb_i = 0;

// Switch SPI to Quad SPI mode
cmd = 8'h1;
for (i = 7; i >= 0; i--) begin
@(negedge spis_sck_i);
spis_sd_i[0] = cmd[i]; // Send 1 bit at a time on MOSI
end
// Enable Quad SPI mode by writing 0x01 to the status register
for (i = 7; i >= 0; i--) begin
@(negedge spis_sck_i);
spis_sd_i[0] = cmd[i]; // Send 1 bit at a time on MOSI
end

@(posedge spis_sck_i);
spis_csb_i = 1; // Bring CSB high to end the transaction
#1us; // Wait for a clock edge to align
@(posedge spis_sck_i);
spis_csb_i = 0; // Bring CSB high to end the transaction

// Set the SPI Write MEM code
cmd = 8'h2;

// Send the command code (8 bits) over 4 data lines (2 clock cycles)
for (i = 7; i >= 0; i -= 4) begin
@(negedge spis_sck_i);
if (i >= 3) begin
mosi_data = cmd[i-:4];
end else begin
// For i = 3 to 0
mosi_data = cmd[3:0];
mosi_data = mosi_data << (3 - i); // Left-align to 4 bits
end
spis_sd_i = mosi_data; // Drive data lines
end

// Send the 32-bit address over 4 data lines (8 clock cycles)
for (i = 31; i >= 0; i -= 4) begin
@(negedge spis_sck_i);
if (i >= 3) begin
mosi_data = addr[i-:4];
end else begin
// For i = 3 to 0
mosi_data = addr[3:0];
mosi_data = mosi_data << (3 - i); // Left-align to 4 bits
end
spis_sd_i = mosi_data; // Drive data lines
end

@(negedge spis_sck_i); // Wait for last data to be sent


// Insert dummy cycles if required (e.g., 32 cycles)
// This is the bug of ETH: @spi_slave_rx.sv, the counter count one more cycles
for (i = 0; i <= 32; i = i + 1) begin
@(posedge spis_sck_i);
// Do nothing, just wait
end

// Now write the data to the slave
// Open the file for reading and get the size of the file
file = $fopen(path, "r");
if (file == 0) begin
$display("Error: Could not open file %s", path);
return;
end
$fseek(file, 0, `SEEK_END);
file_size = $ftell(file);
$fseek(file, 0, `SEEK_SET);

// Read the file in chunks of 4 bytes
for (i = 0; i < file_size; i = i + 1) begin
reg [7:0] byte_data;
byte_data = $fgetc(file);

for (j = 7; j >= 0; j -= 4) begin
@(posedge spis_sck_i);
if (j >= 3) begin
mosi_data = byte_data[j-:4];
end else begin
// For j = 3 to 0
mosi_data = byte_data[3:0] << (3 - j);
end
spis_sd_i = mosi_data; // Drive data lines
end
end
$fclose(file);
$display("Wrote %0d bytes to address %h", file_size, addr);
@(negedge spis_sck_i);

// Bring CSB high to end the transaction
spis_csb_i = 1;
force i_occamy.rst_ni = 0; // Force reset the chip
#10ns;
release i_occamy.rst_ni; // Release reset
endtask
15 changes: 9 additions & 6 deletions target/rtl/test/testharness.sv.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,15 @@ module testharness import occamy_pkg::*; (
logic [3:0] spis_sd_en_o;
logic [3:0] spis_sd_i = '1;

// Inject the signals into SPI device
`include "spi_tb.sv"
initial begin
#1us;
spi_read(32'h80000000, 128);
end
`ifndef TARGET_VSIM
// Inject the signals into SPI device
`include "spi_tb.sv"
initial begin
#10us;
// spi_read(32'h80000000, 128);
spi_write("app.bin", 32'h80000000);
end
`endif

<%def name="tb_memory(bus, name)">
${bus.req_type()} ${name}_req;
Expand Down

0 comments on commit 384af30

Please sign in to comment.