Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ enum {
};

void spi_flash::reset() {
spidpi::reset();
spidevicedpi::reset();
bProgramming = false;
bReading = false;
bErasing = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,16 @@

#include <string.h>

#include "spidpi.hh"
#include "spidevicedpi.hh"

// ----------------------- SPI Flash model ---------------------
class spi_flash : public spidpi {
class spi_flash : public spidevicedpi {
public:
spi_flash(unsigned dataW, // Number of data lines.
unsigned oobInW, // Width of Out-Of-Band input data (bits).
unsigned oobOutW, // Width of Out-Of-Band output data (bits).
uint32_t jedec_id) : // The JEDEC ID of the flash device.
spidpi(dataW, oobInW, oobOutW), jedec_id(jedec_id) {
spidevicedpi(dataW, oobInW, oobOutW), jedec_id(jedec_id) {
reset();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ typedef enum {
// --------

void spi_lcd::reset() {
spidpi::reset();
spidevicedpi::reset();

cmdLen = 0u;
xEnd = xStart = 0u;
Expand Down
6 changes: 3 additions & 3 deletions dv/dpi/spidpi/spi_lcd.hh → dv/dpi/spidevicedpi/spi_lcd.hh
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@

#include <string>

#include "spidpi.hh"
#include "spidevicedpi.hh"

// -------------------- ST7735 LCD model --------------------
class spi_lcd : public spidpi {
class spi_lcd : public spidevicedpi {
public:
spi_lcd(unsigned dataW, // Number of data lines.
unsigned oobInW, // Width of Out-Of-Band input data (bits).
unsigned oobOutW) : // Width of Out-Of-Band output data (bits).
spidpi(dataW, oobInW, oobOutW) {
spidevicedpi(dataW, oobInW, oobOutW) {
reset();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ enum {
static const bool kMustHaveSD = false;

void spi_microsd::reset() {
spidpi::reset();
spidevicedpi::reset();
cmdBytes = 0u;
responding = false;
reading = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@

#include <assert.h>
#include <stdio.h>
#include "spidpi.hh"
#include "spidevicedpi.hh"

// -------------------------- SPI microSD model -------------------------------
class spi_microsd : public spidpi {
class spi_microsd : public spidevicedpi {
public:
spi_microsd(unsigned dataW, // Number of data lines.
unsigned oobInW, // Width of Out-Of-Band input data (bits).
unsigned oobOutW, // Width of Out-Of-Band output data (bits).
const char *sdFile, // Filename of the SD card image.
bool log = false) : // Enable diagnostic logging?
spidpi(dataW, oobInW, oobOutW, log) {
spidevicedpi(dataW, oobInW, oobOutW, log) {
assert(sdFile);
logText("microSD model attempting to open image '%s'\n", sdFile);
sd = fopen(sdFile, "r+b");
Expand Down
32 changes: 16 additions & 16 deletions dv/dpi/spidpi/spidpi.cc → dv/dpi/spidevicedpi/spidevicedpi.cc
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include "spi_lcd.hh"
#include "spi_microsd.hh"

void spidpi::reset() {
void spidevicedpi::reset() {
// Write data to device (COPI).
inByte = 0u;
inBits = 0u;
Expand All @@ -23,7 +23,7 @@ void spidpi::reset() {
// Sampling transition occurred on the SCK line.
// - the function is supplied with the CS, the new COPI data for a write operation as well as the
// Out-Of-Band input signals.
void spidpi::sampleEdge(uint32_t cs, uint32_t copi, uint32_t oobIn) {
void spidevicedpi::sampleEdge(uint32_t cs, uint32_t copi, uint32_t oobIn) {
// Suppress traffic if CS is high because the current SPI model ignores CS.
if ((cs & 1u)) {
return;
Expand All @@ -41,7 +41,7 @@ void spidpi::sampleEdge(uint32_t cs, uint32_t copi, uint32_t oobIn) {
// - the function is supplied with the CS, and the Out-Of-Band input signals.
// - the result sets the Out-of-Band output signals (upper bits) and the CIPO data lines (LSBs) if
// the device is producing read data.
uint32_t spidpi::launchEdge(uint32_t cs, uint32_t oobIn) {
uint32_t spidevicedpi::launchEdge(uint32_t cs, uint32_t oobIn) {
unsigned cipo = 1;
// Suppress traffic if CS is high because the current SPI model ignores CS.
if (cs & 1u) {
Expand All @@ -61,13 +61,13 @@ uint32_t spidpi::launchEdge(uint32_t cs, uint32_t oobIn) {
}

// Transition on one or more CS lines.
void spidpi::csEdge(uint32_t cs, uint32_t oobIn) {
void spidevicedpi::csEdge(uint32_t cs, uint32_t oobIn) {
// Inform the appropriate device(s) of the change the CS line state.
csChanged(!(cs & 1u), oobIn);
}

// Logging utility function.
void spidpi::logText(const char *fmt, ...) {
void spidevicedpi::logText(const char *fmt, ...) {
if (logging) {
va_list va;
va_start(va, fmt);
Expand All @@ -79,12 +79,12 @@ void spidpi::logText(const char *fmt, ...) {
// Interface is using vanilla C, so these functions collect the object pointer.
extern "C" {
// SPI DPI initialisation.
void *spidpi_create(const char *id, // Bus identification.
void *spidevicedpi_create(const char *id, // Bus identification.
unsigned ndevices, // Number of devices on bus (=number of selects).
unsigned dataW, // Number of data lines.
unsigned oobInW, // Width of Out-Of-Band input data (bits).
unsigned oobOutW) { // Width of Out-Of-Band output data (bits).
spidpi *ctx = nullptr;
spidevicedpi *ctx = nullptr;
// TODO: at present we attach only a single device to each SPI bus.
assert(ndevices == 1u);
// Attach the appropriate devices to this bus.
Expand All @@ -97,39 +97,39 @@ void *spidpi_create(const char *id, // Bus identification.
} else if (!strcmp(id, "pmod_sf3")) {
ctx = new spi_flash(dataW, oobInW, oobOutW, 0x20ba19);
} else {
ctx = new spidpi(dataW, oobInW, oobOutW, true);
ctx = new spidevicedpi(dataW, oobInW, oobOutW, true);
ctx->logText("Warning: SPI bus '%s' not recognised", id);
}
assert(ctx);
return (void*)ctx;
}

// SPI DPI finalisation.
void spidpi_destroy(void *ctx_v) {
spidpi *ctx = (spidpi*)ctx_v;
void spidevicedpi_destroy(void *ctx_v) {
spidevicedpi *ctx = (spidevicedpi*)ctx_v;
assert(ctx);
delete ctx;
}

// Sampling transition on the SCK line.
void spidpi_sampleEdge(void *ctx_v, uint32_t cs, uint32_t copi, uint32_t oobIn) {
spidpi *ctx = (spidpi*)ctx_v;
void spidevicedpi_sampleEdge(void *ctx_v, uint32_t cs, uint32_t copi, uint32_t oobIn) {
spidevicedpi *ctx = (spidevicedpi*)ctx_v;
assert(ctx);
ctx->sampleEdge(cs, copi, oobIn);
}

// Launch transition on the SCK line.
uint32_t spidpi_launchEdge(void *ctx_v, uint32_t cs, uint32_t oobIn) {
spidpi *ctx = (spidpi*)ctx_v;
uint32_t spidevicedpi_launchEdge(void *ctx_v, uint32_t cs, uint32_t oobIn) {
spidevicedpi *ctx = (spidevicedpi*)ctx_v;
assert(ctx);
return ctx->launchEdge(cs, oobIn);
}

// Note: This interface is presently inadequate for modelling some devices because they will need
// to know when the CS signal becomes deasserted, and there will not necessarily be a clock
// assertion whilst CS is deasserted.
void spidpi_csEdge(void *ctx_v, uint32_t cs, uint32_t oobIn) {
spidpi *ctx = (spidpi*)ctx_v;
void spidevicedpi_csEdge(void *ctx_v, uint32_t cs, uint32_t oobIn) {
spidevicedpi *ctx = (spidevicedpi*)ctx_v;
assert(ctx);
return ctx->csEdge(cs, oobIn);
}
Expand Down
28 changes: 28 additions & 0 deletions dv/dpi/spidevicedpi/spidevicedpi.core
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
CAPI=2:
# Copyright lowRISC contributors.
# Licensed under the Apache License, Version 2.0, see LICENSE for details.
# SPDX-License-Identifier: Apache-2.0
name: "lowrisc:sonata:spidevicedpi"
description: "SPI device DPI model"

filesets:
files_rtl:
files:
- spidevicedpi.sv: { file_type: systemVerilogSource }

files_c:
files:
- spidevicedpi.cc: { file_type: cppSource }
- spidevicedpi.hh: { file_type: cppSource, is_include_file: true }
- spi_flash.cc: { file_type: cppSource }
- spi_flash.hh: { file_type: cppSource, is_include_file: true }
- spi_lcd.cc: { file_type: cppSource }
- spi_lcd.hh: { file_type: cppSource, is_include_file: true }
- spi_microsd.cc: { file_type: cppSource }
- spi_microsd.hh: { file_type: cppSource, is_include_file: true }

targets:
default:
filesets:
- files_rtl
- files_c
16 changes: 8 additions & 8 deletions dv/dpi/spidpi/spidpi.hh → dv/dpi/spidevicedpi/spidevicedpi.hh
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,28 @@
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0

#ifndef __DV_DPI_SPIDPI_H_
#define __DV_DPI_SPIDPI_H_
#ifndef __DV_DPI_SPIDEVICEDPI_H_
#define __DV_DPI_SPIDEVICEDPI_H_
#include <stdint.h>

// SPI DPI model - this model is supplied with all of the signals and information required to
// support multiple devices on a single SPI bus, but presently the Sonata system employs only a
// single device per bus. Therefore, at present, the SPI device models derive from `spidpi`
// single device per bus. Therefore, at present, the SPI device models derive from `spidevicedpi`
// directly.
//
// If multiple devices are required to share a single bus then a `spi_device` base class may be
// introduced and an instance of `spidpi` will handling the mapping from `cs` line to `spi_device`
// introduced and an instance of `spidevicedpi` will handling the mapping from `cs` line to `spi_device`
// object.
class spidpi {
class spidevicedpi {
public:
spidpi(unsigned dataw, // Number of data lines.
spidevicedpi(unsigned dataw, // Number of data lines.
unsigned oobInw, // Width of Out-Of-Band input data (bits).
unsigned oobOutw, // Width of Out-Of-Band output data (bits).
bool log = false) {
logging = log;
reset();
}
virtual ~spidpi() { }
virtual ~spidevicedpi() { }

// Sampling transition occurred on the SCK line.
void sampleEdge(uint32_t cs, uint32_t copi, uint32_t oobIn);
Expand Down Expand Up @@ -71,4 +71,4 @@ private:
// Most recent Out-Of-Band output data.
uint32_t oobOut;
};
#endif // __DV_DPI_SPIDPI_H_
#endif // __DV_DPI_SPIDEVICEDPI_H_
24 changes: 12 additions & 12 deletions dv/dpi/spidpi/spidpi.sv → dv/dpi/spidevicedpi/spidevicedpi.sv
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// so the device launches data on the falling edge.
// - the SPI controller within the Sonata system does support other modes of operation but these
// are not presently required by the devices that are being simulated.
module spidpi #(
module spidevicedpi #(
// Device identification.
parameter string ID = "generic",
// Number of SPI devices on the bus (= number of chip selects).
Expand Down Expand Up @@ -36,26 +36,26 @@ module spidpi #(
chandle ctx;

// Note: The imported DPI-C functions use 'int unsigned' for their parameters rather than
// parameterising their widths because the module `spidpi` is multiply-instantiated and that would
// parameterising their widths because the module `spidevicedpi` is multiply-instantiated and that would
// lead to Verilator complaining about multiple incompatible signatures for each imported function.

// SPI DPI initialisation; DPI model is supplied with the device identification string and the
// properties of the physical connections.
import "DPI-C" function
chandle spidpi_create(input string name, // Device identification string.
chandle spidevicedpi_create(input string name, // Device identification string.
input int ndevices, // Number of devices on bus (= number of selects).
input int dataW, // Number of data lines.
input int oobIntW, // Width of Out-Of-Band input data (bits).
input int oobOutW); // Width of Out-Of-Band output data (bits).
// SPI DPI finalisation.
import "DPI-C" function
void spidpi_destroy(input chandle ctx);
void spidevicedpi_destroy(input chandle ctx);

// Sampling transition occurred on the SCK line.
// - the function is supplied with the new COPI data for a write operation as well as the
// Out-Of-Band input signals.
import "DPI-C" function
void spidpi_sampleEdge(input chandle ctx,
void spidevicedpi_sampleEdge(input chandle ctx,
input int unsigned cs, // Chip Selects.
input int unsigned copi, // Write data from controller.
input int unsigned oob_in); // Out-Of-Band inputs.
Expand All @@ -65,43 +65,43 @@ import "DPI-C" function
// - the result is used to set the new state of the Out-Of-Band output signals (upper bits) and the
// read data line(s) to the controller (CIPO).
import "DPI-C" function
bit [OOB_OutW+DataW-1:0] spidpi_launchEdge(input chandle ctx,
bit [OOB_OutW+DataW-1:0] spidevicedpi_launchEdge(input chandle ctx,
input int unsigned cs, // Chip Selects.
input int unsigned oob_in); // Out-Of-Band inputs.

// Report a transition on the CS lines; some devices need to be aware of deselection so that an
// ongoing write/read operation may be terminated and a new command accepted.
// - the function is supplied with the new state of the CS lines and the Out-Of-Band input signals.
import "DPI-C" function
void spidpi_csEdge(input chandle ctx,
void spidevicedpi_csEdge(input chandle ctx,
input int unsigned cs, // Chip Selects.
input int unsigned oob_in); // Out-Of-Band inputs.

// Initialisation of DPI model.
initial begin
ctx = spidpi_create(ID, NDevices, DataW, OOB_InW, OOB_OutW);
ctx = spidevicedpi_create(ID, NDevices, DataW, OOB_InW, OOB_OutW);
end
// Finalisation of DPI model.
final begin
spidpi_destroy(ctx);
spidevicedpi_destroy(ctx);
end

// Sampling of write data into the device (COPI).
always_ff @(posedge sck or negedge rst_ni) begin
// Do not invoke the device logic within reset
if (rst_ni) spidpi_sampleEdge(ctx, 32'(cs), 32'(copi), 32'(oob_in));
if (rst_ni) spidevicedpi_sampleEdge(ctx, 32'(cs), 32'(copi), 32'(oob_in));
end

// Launching of read data from the device (CIPO).
logic [OOB_OutW+DataW-1:0] out_q;
always_ff @(negedge sck or negedge rst_ni) begin
if (!rst_ni) out_q <= '0;
else out_q <= spidpi_launchEdge(ctx, 32'(cs), 32'(oob_in));
else out_q <= spidevicedpi_launchEdge(ctx, 32'(cs), 32'(oob_in));
end

// Report transitions on the CS lines.
always @(cs) begin
spidpi_csEdge(ctx, 32'(cs), 32'(oob_in));
spidevicedpi_csEdge(ctx, 32'(cs), 32'(oob_in));
end

assign {oob_out, cipo} = out_q;
Expand Down
Loading
Loading