diff --git a/src/groovylight/bitslicer.py b/src/groovylight/bitslicer.py index 060aa9e..b04474f 100644 --- a/src/groovylight/bitslicer.py +++ b/src/groovylight/bitslicer.py @@ -8,7 +8,6 @@ from amaranth.utils import ceil_log2 from .common import Rgb666Layout, Hub75Stream, Hub75Ctrl, Hub75Data - class SwapBuffer(wiring.Component): """A pair of BRAMs for holdling line data that are swapped between using an external signal. diff --git a/src/groovylight/main.py b/src/groovylight/main.py index fd11adc..0cd9bda 100644 --- a/src/groovylight/main.py +++ b/src/groovylight/main.py @@ -1,10 +1,8 @@ # main entry point for CLI applications. - import logging import argparse - logger = logging.getLogger(__loader__.name) @@ -12,9 +10,7 @@ def setup_logger(args): root_logger = logging.getLogger() handler = logging.StreamHandler() - formatter = logging.Formatter( - style="{", fmt="{levelname:s}: {name:s}: {message:s}" - ) + formatter = logging.Formatter(style="{", fmt="{levelname:s}: {name:s}: {message:s}") handler.setFormatter(formatter) root_logger.addHandler(handler) @@ -33,6 +29,7 @@ def main(): const=logging.DEBUG, default=logging.INFO, ) + parser.add_argument( "-L", "--log-file", diff --git a/src/groovylight/platforms/__init__.py b/src/groovylight/platforms/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/groovylight/platforms/colorlight_5a75b_v8_2.py b/src/groovylight/platforms/colorlight_5a75b_v8_2.py index 6d5713a..a877bd5 100644 --- a/src/groovylight/platforms/colorlight_5a75b_v8_2.py +++ b/src/groovylight/platforms/colorlight_5a75b_v8_2.py @@ -23,7 +23,9 @@ class Colorlight_5A75B_R82Platform(LatticeECP5Platform): Subsignal("copi", Pins("T8", dir="o")), Attrs(IO_TYPE="LVCMOS33"), ), - *LEDResources(pins="T6", invert=True, attrs=Attrs(IO_TYPE="LVCMOS33", DRIVE="4")), + *LEDResources( + pins="T6", invert=True, attrs=Attrs(IO_TYPE="LVCMOS33", DRIVE="4") + ), *ButtonResources( pins="R7", invert=True, attrs=Attrs(IO_TYPE="LVCMOS33", PULLMODE="UP") ), diff --git a/src/groovylight/sdram.py b/src/groovylight/sdram.py index 29b6c0b..adbf1d5 100644 --- a/src/groovylight/sdram.py +++ b/src/groovylight/sdram.py @@ -13,67 +13,80 @@ from amaranth.lib.wiring import In, Out # word size = 32 # 8 megabytes data. + class SDRAMSignature(wiring.Signature): - """ Signature of a variable-size sdram. Data is split between in/out and has out_en""" + """Signature of a variable-size sdram. Data is split between in/out and has out_en""" + def __init__(self, addr_width, data_width=32, bank_width=2): - super().__init__({ - "nCS": Out(1), - "cke": Out(1), - "nRAS": Out(1), - "nCAS": Out(1), - "nWE": Out(1), - "addr": Out(addr_width), - "data_out": Out(data_width), - "data_in": In(data_width), - # todo: use dqm - "data_wren": Out(1), - "bank_cs": Out(bank_width), - }) + super().__init__( + { + "nCS": Out(1), + "cke": Out(1), + "nRAS": Out(1), + "nCAS": Out(1), + "nWE": Out(1), + "addr": Out(addr_width), + "data_out": Out(data_width), + "data_in": In(data_width), + # todo: use dqm + "data_wren": Out(1), + "bank_cs": Out(bank_width), + } + ) + class _WriteBurstLength(enum.Enum, shape=1): """MRS Write burst mode""" + BURST = 0 SINGLE_BIT = 1 + class _TestMode(enum.Enum, shape=2): - """ The "test mode" of the sdram. This is always zero pretty much""" + """The "test mode" of the sdram. This is always zero pretty much""" + MODE_REGISTER_SET = 0 RESERVED0 = 1 RESERVED1 = 2 RESERVED2 = 3 + class _CASLatency(enum.Enum, shape=3): - """ How many cycles of latency for the column address select to complete """ + """How many cycles of latency for the column address select to complete""" + CYCL2 = 2 CYCL3 = 3 + class _BurstType(enum.Enum, shape=1): SEQUENTIAL = 0 INTERLEAVED = 1 + class _BurstLength(enum.IntEnum, shape=3): - """ The size of the burst """ + """The size of the burst""" + SINGLE = 0 DUAL = 1 QUAD = 2 OCT = 3 - FULL_PAGE = 7 # this is 256 words? + FULL_PAGE = 7 # this is 256 words? class _Command(enum.Enum): - """ Command set for SDRAM """ + """Command set for SDRAM""" + MRS_WRITE = 0 ACTIVATE = 1 PRECHARGE = 2 WRITE = 3 READ = 4 - CBR = 5 # auto refresh + CBR = 5 # auto refresh SELF_REFRESH = 6 BRST_STOP = 7 NOP = 8 - class BankController(wiring.Component): """Manages a single Bank. Has a bank locking/state tracker, can issue commands""" diff --git a/src/groovylight/tests/test_geom.py b/src/groovylight/tests/test_geom.py index cc698dd..fdba69c 100644 --- a/src/groovylight/tests/test_geom.py +++ b/src/groovylight/tests/test_geom.py @@ -2,11 +2,12 @@ from ..geom import Coord, BBox import pytest + def test_coord_comparison(): - c1 = Coord(0,0) - c2 = Coord(0,1) - c3 = Coord(1,1) - c3_other = Coord(1,1) + c1 = Coord(0, 0) + c2 = Coord(0, 1) + c3 = Coord(1, 1) + c3_other = Coord(1, 1) assert c1 < c3 assert not c1 < c2, "both x,y must be greater/lt/eq" @@ -15,23 +16,24 @@ def test_coord_comparison(): assert c3 == c3_other, "Coords with same numbers should equal each other" assert c3 != c2 + def test_coord_construction(): with pytest.raises(RuntimeError): - Coord(0,-1) + Coord(0, -1) def test_bbox(): - b = BBox(Coord(1,1), Coord(3,2)) + b = BBox(Coord(1, 1), Coord(3, 2)) assert b.width == 2 assert b.height == 1 - assert b.contains(Coord(1,2)) - assert not b.contains(Coord(0,0)) - + assert b.contains(Coord(1, 2)) + assert not b.contains(Coord(0, 0)) + # TODO: test .intersect(other) with pytest.raises(RuntimeError): - BBox(Coord(0,0), Coord(1,0)) + BBox(Coord(0, 0), Coord(1, 0)) with pytest.raises(RuntimeError): - BBox(Coord(1,1), Coord(0,0)) + BBox(Coord(1, 1), Coord(0, 0)) diff --git a/src/groovylight/tests/test_swapbuffer.py b/src/groovylight/tests/test_swapbuffer.py index 6326b11..e1498a9 100644 --- a/src/groovylight/tests/test_swapbuffer.py +++ b/src/groovylight/tests/test_swapbuffer.py @@ -25,9 +25,11 @@ def test_swapbuffer(): assert ctx.get(dut.read_port.data) == init_color # swap buffer ctx.set(dut.selector, 1) - await ctx.tick().repeat(2) # takes two clocks after switching selector to output data. + await ctx.tick().repeat( + 2 + ) # takes two clocks after switching selector to output data. assert ctx.get(dut.read_port.data) == test_color - + # TODO: add more assertions/verification sim.add_testbench(testbench) with sim.write_vcd("output.vcd"):