Skip to content

Instantly share code, notes, and snippets.

@twam
Created January 25, 2021 20:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save twam/51733f6ae1c9fd7f53bd5ab05060b410 to your computer and use it in GitHub Desktop.
Save twam/51733f6ae1c9fd7f53bd5ab05060b410 to your computer and use it in GitHub Desktop.
seven_segment_serial.py
from typing import List, Dict
from enum import IntEnum
from nmigen import *
from nmigen.utils import *
from nmigen.back.pysim import *
from nibble_to_segments import *
from tlc591x import *
class SevenSegmentSerialState(IntEnum):
CONVERT = 0,
TRANSMIT = 1
class SevenSegmentSerial(Elaboratable):
def __init__(self, number_of_digits = 1):
self.number_of_digits = number_of_digits
# SPI
self.do = Signal(reset=0)
self.sclk = Signal(reset=0)
self.le = Signal(reset=0)
self.oe = Signal(reset=1) # Output is disabled by default
# Data
self.data = Signal(self.number_of_digits*4)
self.data_segments = Signal(self.number_of_digits*8)
# Internal
self.state = Signal(SevenSegmentSerialState)
self.nibble = Signal(4)
self.segments = Signal(8)
self.counter = Signal(5)
def ports(self) -> List[Signal]:
return []
def elaborate(self, platform) -> Module:
m = Module()
m.submodules.nibble_to_segments = nibble_to_segments = NibbleToSegments()
m.d.comb += nibble_to_segments.nibble.eq(self.nibble)
m.d.comb += self.segments.eq(nibble_to_segments.segments)
m.submodules.tlc591x = tlc591x = Tlc591x(number_of_chips = self.number_of_digits)
m.d.comb += tlc591x.data.eq(self.data_segments)
m.d.comb += self.do.eq(tlc591x.do)
m.d.comb += self.sclk.eq(tlc591x.sclk)
m.d.comb += self.le.eq(tlc591x.le)
m.d.comb += self.oe.eq(tlc591x.oe)
m.d.sync += self.counter.eq(self.counter + 1)
m.d.comb += tlc591x.latch.eq(0)
with m.Switch(self.state):
with m.Case(SevenSegmentSerialState.CONVERT):
# m.d.comb += self.nibble.eq(self.data.word_select(self.number_of_digits-1-self.counter, 4))
m.d.comb += self.nibble.eq(self.data.bit_select((self.number_of_digits-1-self.counter)*4, 4))
# m.d.sync += self.data_segments.word_select(self.counter, 8).eq(self.segments)
m.d.sync += self.data_segments.bit_select(self.counter*8, 8).eq(self.segments)
with m.If(self.counter == self.number_of_digits-1):
self.switch_state(m, SevenSegmentSerialState.TRANSMIT)
with m.Case(SevenSegmentSerialState.TRANSMIT):
with m.If(self.counter == 0):
m.d.comb += tlc591x.latch.eq(1)
with m.If(self.counter == 1):
with m.If(tlc591x.ready == 0):
m.d.sync += self.counter.eq(1)
with m.Else():
self.switch_state(m, SevenSegmentSerialState.CONVERT)
return m
def switch_state(self, m: Module, state: SevenSegmentSerialState):
m.d.sync += self.counter.eq(0)
m.d.sync += self.state.eq(state)
if __name__ == "__main__":
dut = SevenSegmentSerial(number_of_digits = 4)
sim = Simulator(dut)
sim.add_clock(1e-6)
def process():
yield dut.data.eq(0x0123)
for i in range(dut.data.width*4*2+10):
yield
sim.add_sync_process(process)
with sim.write_vcd('seven_segment_serial.vcd', 'seven_segment_serial.gtkw', traces=[]+dut.ports()):
sim.run()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment