Skip to content

Commit

Permalink
Cleanup 6502 example
Browse files Browse the repository at this point in the history
  • Loading branch information
freand76 committed Jan 28, 2023
1 parent 6881c8d commit 9d3505c
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 64 deletions.
56 changes: 3 additions & 53 deletions examples/yosys_6502/example_yosys_6502.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,7 @@
import os

from digsim.circuit import Circuit
from digsim.circuit.components import Clock, PushButton, YosysComponent
from digsim.circuit.components.atoms import Component, PortIn, PortOut, PortWire


class Memory(Component):
def __init__(self, circuit, rom_filename=None, rom_address=0):
super().__init__(circuit, "Memory")
self.add_port(PortIn(self, "clk"))
self.add_port(PortWire(self, "Address", width=16))
self.add_port(PortWire(self, "DataIn", width=8))
self.add_port(PortWire(self, "WE"))
self.add_port(PortOut(self, "DataOut", width=8))
self._mem_array = [0] * 65536
if rom_filename is not None:
with open(rom_filename, mode="rb") as rom:
romdata = rom.read()
for idx, byte in enumerate(romdata):
self._mem_array[rom_address + idx] = byte

def update(self):
if not self.is_rising_edge(self.clk) or self.Address.value == "X":
return
addr = self.Address.value
we = self.WE.value
if we == 1:
datain = self.DataIn.value
self._mem_array[addr] = datain
else:
dataout = self._mem_array[addr]
self.DataOut.value = dataout


class StringOutput(Component):
def __init__(self, circuit):
super().__init__(circuit, "StringOutput")
self.add_port(PortIn(self, "clk"))
self.add_port(PortWire(self, "Address", width=16))
self.add_port(PortWire(self, "DataIn", width=8))
self.add_port(PortWire(self, "WE"))
self._str = ""

def update(self):
if self.WE.value == 0 or self.Address.value != 0x8000:
return
if self.is_rising_edge(self.clk):
datain = self.DataIn.value
if datain == 0x0A:
print(f"OUTPUT: '{self._str}'")
self._str = ""
else:
self._str += chr(datain)
from digsim.circuit.components import Clock, Mem64kByte, MemStdOut, PushButton, YosysComponent


test_circuit = Circuit(vcd="6502.vcd")
Expand All @@ -64,10 +14,10 @@ def update(self):
rdy = PushButton(test_circuit, "RDY")

yosys_6502 = YosysComponent(test_circuit, filename=f"{os.path.dirname(__file__)}/6502.json")
mem = Memory(
mem = Mem64kByte(
test_circuit, rom_filename=f"{os.path.dirname(__file__)}/code.bin", rom_address=0xF800
)
output = StringOutput(test_circuit)
output = MemStdOut(test_circuit, address=0x8000)

clk.wire = mem.clk
yosys_6502.AB.wire = mem.Address
Expand Down
2 changes: 2 additions & 0 deletions src/digsim/circuit/components/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from ._gates import AND, NAND, NOT, SR, XOR # noqa: F401
from ._hexdigit import HexDigit # noqa: F401
from ._led import Led # noqa: F401
from ._mem64kbyte import Mem64kByte # noqa: F401
from ._memstdout import MemStdOut # noqa: F401
from ._on_off_switch import OnOffSwitch # noqa: F401
from ._power import GND, VDD # noqa: F401
from ._seven_segment import SevenSegment # noqa: F401
Expand Down
32 changes: 32 additions & 0 deletions src/digsim/circuit/components/_mem64kbyte.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright (c) Fredrik Andersson, 2023
# All rights reserved

from digsim.circuit.components.atoms import Component, PortIn, PortOut, PortWire


class Mem64kByte(Component):
def __init__(self, circuit, rom_filename=None, rom_address=0):
super().__init__(circuit, "Memory")
self.add_port(PortIn(self, "clk"))
self.add_port(PortWire(self, "Address", width=16))
self.add_port(PortWire(self, "DataIn", width=8))
self.add_port(PortWire(self, "WE"))
self.add_port(PortOut(self, "DataOut", width=8))
self._mem_array = [0] * 65536
if rom_filename is not None:
with open(rom_filename, mode="rb") as rom:
romdata = rom.read()
for idx, byte in enumerate(romdata):
self._mem_array[rom_address + idx] = byte

def update(self):
if not self.clk.is_rising_edge() or self.Address.value == "X":
return
addr = self.Address.value
we = self.WE.value
if we == 1:
datain = self.DataIn.value
self._mem_array[addr] = datain
else:
dataout = self._mem_array[addr]
self.DataOut.value = dataout
28 changes: 28 additions & 0 deletions src/digsim/circuit/components/_memstdout.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright (c) Fredrik Andersson, 2023
# All rights reserved

from digsim.circuit.components.atoms import Component, PortIn, PortWire


class MemStdOut(Component):
def __init__(self, circuit, address=0x8000):
super().__init__(circuit, "MemStdOut")
self._address = address
self.add_port(PortIn(self, "clk"))
self.add_port(PortWire(self, "Address", width=16))
self.add_port(PortWire(self, "DataIn", width=8))
self.add_port(PortWire(self, "WE"))
self._str = ""

def update(self):
if self.WE.value == 0 or self.Address.value != self._address:
return
if self.clk.is_rising_edge():
datain = self.DataIn.value
if datain == 0x0A:
print(f"StringOutput [line]: '{self._str}'")
self._str = ""
else:
inchar = chr(datain)
print(f"StringOutput [char]: '{inchar}'")
self._str += inchar
11 changes: 0 additions & 11 deletions src/digsim/circuit/components/atoms/_component.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,17 +99,6 @@ def remove_connections(self):
def add_event(self, port, value, delay_ns):
self.circuit.add_event(port, value, delay_ns)

def is_rising_edge(self, port):
rising_edge = False
if (
port.value == 1
and port in self._edge_detect_dict
and self._edge_detect_dict[port] == 0
):
rising_edge = True
self._edge_detect_dict[port] = port.value
return rising_edge

def __str__(self):
comp_str = f"{self.display_name()}"
for port in self.inports():
Expand Down
15 changes: 15 additions & 0 deletions src/digsim/circuit/components/atoms/_port.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ def __init__(self, parent, name, width=1, output=False):
self._output = output # Is this port an output port
self._wired_ports = [] # The ports that this port drives
self._value = None # The value of this port
self._edge_detect_value = "X" # Last edge detect value
self.init() # Initialize the port

@property
Expand Down Expand Up @@ -82,6 +83,20 @@ def is_output(self):
def is_input(self):
return not self._output

def is_rising_edge(self):
rising_edge = False
if self.value == 1 and self._edge_detect_value == 0:
rising_edge = True
self._edge_detect_value = self.value
return rising_edge

def is_falling_edge(self):
falling_edge = False
if self.value == 0 and self._edge_detect_value == 1:
falling_edge = True
self._edge_detect_value = self.value
return falling_edge

@abc.abstractmethod
def set_value(self, value):
pass
Expand Down

0 comments on commit 9d3505c

Please sign in to comment.