Skip to content
Draft
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
31 changes: 25 additions & 6 deletions lib/src/gaskets/spi/spi_main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class SpiMain extends Module {
required Logic reset,
required Logic start,
required Logic busIn,
Logic? css,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add documentation for what css is

super.name = 'spiMain'}) {
busIn = addInput('busIn', busIn, width: busIn.width);

Expand All @@ -42,6 +43,10 @@ class SpiMain extends Module {

start = addInput('start', start);

if (css != null) {
css = addInput('css', css, width: intf.multiChipSelects);
}

addOutput('busOut', width: busIn.width);

addOutput('done');
Expand All @@ -50,11 +55,15 @@ class SpiMain extends Module {
..pairConnectIO(this, intf, PairRole.provider);

final isRunning = Logic(name: 'isRunning');
final active = Logic(name: 'enable');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did you mean to call this "active"?


// Active will be high when start is pulsed high or isRunning is high.
active <= start | isRunning;

// Counter to track of the number of bits shifted out.
final count = Counter.simple(
clk: ~clk,
enable: start | isRunning,
enable: active,
reset: reset,
asyncReset: true,
resetValue: busIn.width - 1,
Expand Down Expand Up @@ -87,11 +96,21 @@ class SpiMain extends Module {
// NOTE: dataStage0 corresponds to the last bit shifted in.
busOut <= shiftReg.stages.rswizzle();

// SCLK runs off clk when isRunning is true or start is pulsed high.
intf.sclk <= ~clk & (isRunning | start);

// CS is active low. It will go low when isRunning or start is pulsed high.
intf.csb <= ~(isRunning | start);
// SCLK runs off clk when active.
intf.sclk <= ~clk & active;

// CS is active low. It will go low when active for single sub.
// if multiple sub, css will be used to control each csb.

if (css != null) {
for (var i = 0; i < intf.multiChipSelects; i++) {
intf.csb[i] <= ~(~css[i] & active);
}
} else {
for (var i = 0; i < intf.multiChipSelects; i++) {
intf.csb[i] <= ~active;
}
}

// MOSI is connected shift register dataOut.
intf.mosi <=
Expand Down
27 changes: 17 additions & 10 deletions lib/src/gaskets/spi/spi_sub.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ class SpiSub extends Module {
{required SpiInterface intf,
Logic? busIn,
Logic? reset,
bool triStateOutput = false,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

document triStateOutput

super.name = 'spiSub'}) {
// SPI Interface
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we add validation that the interface always has 1 CS?

intf = SpiInterface.clone(intf)
Expand All @@ -50,10 +51,10 @@ class SpiSub extends Module {

addOutput('done');

// Counter to track of the number of bits shifted out.
// Counter to track the number of bits shifted out.
final count = Counter.simple(
clk: intf.sclk,
enable: ~intf.csb,
enable: ~intf.csb[0],
reset: reset,
asyncReset: true,
resetValue: intf.dataLength - 1,
Expand All @@ -70,7 +71,7 @@ class SpiSub extends Module {
// NOTE: Reset values are set to busIn values.
final shiftReg = ShiftRegister(
intf.mosi,
enable: ~intf.csb,
enable: ~intf.csb[0],
clk: intf.sclk,
depth: intf.dataLength,
reset: reset,
Expand All @@ -82,12 +83,18 @@ class SpiSub extends Module {
// NOTE: dataStage0 corresponds to the last bit shifted in.
busOut <= shiftReg.stages.rswizzle();

// MISO is connected to shift register dataOut.
intf.miso <=
flop(~intf.sclk, shiftReg.dataOut,
en: ~intf.csb,
reset: reset,
asyncReset: true,
resetValue: busIn?[-1]);
// flop data from shift register dataOut.
final flopDataOut = FlipFlop(~intf.sclk, shiftReg.dataOut,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: why not keep it as a flop like it was?

en: ~intf.csb[0],
reset: reset,
asyncReset: true,
resetValue: busIn?[-1]);

// Connect flopDataOut to MISO via tri-state buffer if enabled.
if (triStateOutput) {
intf.miso <= TriStateBuffer(flopDataOut.q, enable: ~intf.csb[0]).out;
} else {
intf.miso <= flopDataOut.q;
}
}
}
15 changes: 10 additions & 5 deletions lib/src/interfaces/spi.dart
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does the SPI checker need updating as well?

Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,31 @@ class SpiInterface extends PairInterface {
/// The data length for serial transmissions on this interface.
final int dataLength;

/// The number of Chip Select signals in this interface.
final int multiChipSelects;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why no numChipSelects or something?


/// Serial clock (SCLK). Clock signal from main to sub(s).
Logic get sclk => port('SCLK');

/// Main Out Sub In (MOSI). Serial data from main to sub(s).
Logic get mosi => port('MOSI');

/// Main In Sub Out (MISO). Serial data from sub(s) to main.
Logic get miso => port('MISO');
LogicNet get miso => port('MISO') as LogicNet;

/// Chip select (active low). Chip select signal from main to sub.
Logic get csb => port('CSB');
List<Logic> get csb => List.generate(multiChipSelects, (i) => port('CSB$i'));

/// Creates a new [SpiInterface].
SpiInterface({this.dataLength = 1})
SpiInterface({this.dataLength = 1, this.multiChipSelects = 1})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

validation: do you want to check that these inputs are valid? both of these should be >= 1 right?

: super(
portsFromConsumer: [Port('MISO')],
portsFromProvider: [Port('MOSI'), Port('CSB'), Port('SCLK')]);
portsFromConsumer: [LogicNet.port('MISO')],
portsFromProvider: [Port('MOSI'), Port('SCLK')] +
List.generate(multiChipSelects, (i) => Port('CSB$i')));

/// Clones this [SpiInterface].
SpiInterface.clone(SpiInterface super.otherInterface)
: dataLength = otherInterface.dataLength,
multiChipSelects = otherInterface.multiChipSelects,
super.clone();
}
6 changes: 3 additions & 3 deletions lib/src/models/spi_bfm/spi_main_driver.dart
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class SpiMainDriver extends PendingClockedDriver<SpiPacket> {
unawaited(super.run(phase));

Simulator.injectAction(() {
intf.csb.put(1);
intf.csb[0].put(1);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is incomplete on the BFM side, right? we need ways to drive different CSB's, not just always 0

intf.mosi.put(0);
});

Expand All @@ -48,7 +48,7 @@ class SpiMainDriver extends PendingClockedDriver<SpiPacket> {
} else {
await clk.nextNegedge;
Simulator.injectAction(() {
intf.csb.put(1);
intf.csb[0].put(1);
_clkenable.inject(0);
intf.mosi.put(0);
});
Expand All @@ -61,7 +61,7 @@ class SpiMainDriver extends PendingClockedDriver<SpiPacket> {

/// Drives a packet onto the interface.
Future<void> _drivePacket(SpiPacket packet) async {
intf.csb.inject(0);
intf.csb[0].inject(0);

// Loop through the bits of the packet
for (var i = 1; i <= packet.data.width; i++) {
Expand Down
2 changes: 1 addition & 1 deletion lib/src/models/spi_bfm/spi_sub_driver.dart
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we add validation that the interface always has 1 CS?

Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class SpiSubDriver extends PendingDriver<SpiPacket> {

intf.miso.inject(0);

intf.csb.negedge.listen((_) {
intf.csb[0].negedge.listen((_) {
_packetHandler(loadOnly: true);
});

Expand Down
Loading
Loading