Skip to content

Commit

Permalink
add spi master
Browse files Browse the repository at this point in the history
  • Loading branch information
UnsignedByte committed Mar 16, 2024
1 parent c00878f commit 54c8467
Show file tree
Hide file tree
Showing 7 changed files with 2,434 additions and 1 deletion.
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,6 @@ ENV/
env.bak/
venv.bak/

.hypothesis/
.hypothesis/

core.*
25 changes: 25 additions & 0 deletions src/regs/shift/bitwise.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from pymtl3 import mk_bits, InPort, OutPort, Component
from pymtl3.passes.backends.verilog import VerilogPlaceholder, VerilogPlaceholderPass
from os import path


class ComplexMultiplier(VerilogPlaceholder, Component):
# Constructor
def construct(s, p_nbits, p_reset_value):
# Interface
s.d = InPort()
s.en = InPort()

s.override = InPort(mk_bits(p_nbits))
s.override_en = InPort()

s.q = OutPort(mk_bits(p_nbits))

# Source file path
s.set_metadata(
VerilogPlaceholderPass.src_file,
path.join(path.dirname(__file__), "bitwise.v"),
)

# Name of the top level module to be imported
s.set_metadata(VerilogPlaceholderPass.top_module, "Bitwise")
52 changes: 52 additions & 0 deletions src/regs/shift/bitwise.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@

`ifndef REGS_SHIFT_BITWISE
`define REGS_SHIFT_BITWISE
//------------------------------------------------------------------------
// N-bit bitwise shift register
//------------------------------------------------------------------------
/*
This is a shift register storing `nbits` total bits.
One bit of data can be inputted per clock cycle, gated by the `en` input.
The entire register will be shifted to the left by one bit when this happens.
For example, here is a simulation of a 4 bit register:
```
reset held high
0000
en high, d = 1
0001
en high, d = 0
0010
override_en high, override = 1111
1111
```
The entire register can be overridden by the `override` input when `override_en` is high.
Data cannot be inputted when `override_en` is high.
*/
module regs_shift_Bitwise #(
parameter p_nbits = 8,
parameter p_reset_value = 0
) (
input logic clk, // Clock input
input logic reset, // Sync reset input
input logic d, // One bit data input
input logic en, // Enable input
input logic [p_nbits-1:0] override, // Override data input
input logic override_en, // Enable override
output logic [p_nbits-1:0] q // Data output
);

always_ff @(posedge clk) begin
if (reset) begin
q <= {p_nbits{p_reset_value}};
end else if (override_en) begin
q <= override;
end else if ((~override_en) & en) begin
q <= {q[p_nbits-2:0], d};
end
end
endmodule

`endif
Empty file added src/spi/__init__.py
Empty file.
46 changes: 46 additions & 0 deletions src/spi/master.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
from os import path
from pymtl3 import mk_bits, Component, clog2, InPort, OutPort, Interface
from pymtl3.passes.backends.verilog import *
from pymtl3.stdlib.stream.ifcs import RecvIfcRTL, SendIfcRTL


# PYMTL interface for the SPI Master
class SPIMasterIfc(Interface):
def construct(s, ncs):
s.cs = [OutPort() for _ in range(ncs)]
s.sclk = OutPort()
s.mosi = OutPort()
s.miso = InPort()

def __str__(s):
return f"{s.sclk}|{s.cs}|{s.mosi}|{s.miso}"


class SPIMaster(VerilogPlaceholder, Component):
# Constructor
def construct(s, nbits=34, ncs=1):
# Local parameters
s.nbits = nbits # size of message
s.ncs = ncs # number of chip select lines
s.logBitsN = mk_bits(
clog2(nbits) + 1
) # number of bits required to count to packet size

# Interface
s.spi_ifc = SPIMasterIfc(ncs)

s.send = SendIfcRTL(mk_bits(s.nbits))
s.recv = RecvIfcRTL(mk_bits(s.nbits))

s.packet_size_ifc = RecvIfcRTL(s.logBitsN) # size of spi packet (up to nbits)
s.cs_addr_ifc = RecvIfcRTL(mk_bits(clog2(s.ncs) if s.ncs > 1 else 1))
s.freq_ifc = RecvIfcRTL(mk_bits(3))

# Source file path
s.set_metadata(
VerilogPlaceholderPass.src_file,
path.join(path.dirname(__file__), "master.v"),
)

# Name of the top level module to be imported
s.set_metadata(VerilogPlaceholderPass.top_module, "Master")
Loading

0 comments on commit 54c8467

Please sign in to comment.