add component library with UART
This commit is contained in:
parent
cf6ebc9953
commit
55e12d3185
@ -3,4 +3,5 @@ rec {
|
|||||||
nmigen = pkgs.callPackage ./nmigen.nix {};
|
nmigen = pkgs.callPackage ./nmigen.nix {};
|
||||||
jtagtap = pkgs.callPackage ./jtagtap.nix { inherit nmigen; };
|
jtagtap = pkgs.callPackage ./jtagtap.nix { inherit nmigen; };
|
||||||
minerva = pkgs.callPackage ./minerva.nix { inherit nmigen; inherit jtagtap; };
|
minerva = pkgs.callPackage ./minerva.nix { inherit nmigen; inherit jtagtap; };
|
||||||
|
heavycomps = pkgs.callPackage ./heavycomps.nix { inherit nmigen; };
|
||||||
}
|
}
|
||||||
|
16
heavycomps.nix
Normal file
16
heavycomps.nix
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{ stdenv, python3Packages, nmigen }:
|
||||||
|
|
||||||
|
python3Packages.buildPythonPackage {
|
||||||
|
name = "heavycomps";
|
||||||
|
|
||||||
|
src = ./heavycomps;
|
||||||
|
|
||||||
|
propagatedBuildInputs = [ nmigen ];
|
||||||
|
|
||||||
|
meta = with stdenv.lib; {
|
||||||
|
description = "Components for the HeavyX SoC toolkit";
|
||||||
|
homepage = "https://m-labs.hk/migen";
|
||||||
|
license = licenses.bsd2;
|
||||||
|
maintainers = [ maintainers.sb0 ];
|
||||||
|
};
|
||||||
|
}
|
0
heavycomps/heavycomps/__init__.py
Normal file
0
heavycomps/heavycomps/__init__.py
Normal file
110
heavycomps/heavycomps/uart.py
Normal file
110
heavycomps/heavycomps/uart.py
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
from nmigen import *
|
||||||
|
from nmigen.lib.cdc import MultiReg
|
||||||
|
from nmigen.cli import main
|
||||||
|
|
||||||
|
|
||||||
|
class RS232RX:
|
||||||
|
def __init__(self, tuning_word):
|
||||||
|
self.rx = Signal()
|
||||||
|
self.data = Signal(8)
|
||||||
|
self.stb = Signal()
|
||||||
|
self.tuning_word = tuning_word
|
||||||
|
|
||||||
|
def elaborate(self, platform):
|
||||||
|
m = Module()
|
||||||
|
|
||||||
|
uart_clk_rxen = Signal()
|
||||||
|
phase_accumulator_rx = Signal(32)
|
||||||
|
|
||||||
|
rx = Signal()
|
||||||
|
m.submodules += MultiReg(self.rx, rx)
|
||||||
|
rx_r = Signal()
|
||||||
|
rx_reg = Signal(8)
|
||||||
|
rx_bitcount = Signal(4)
|
||||||
|
rx_busy = Signal()
|
||||||
|
rx_done = self.stb
|
||||||
|
rx_data = self.data
|
||||||
|
m.d.sync += rx_done.eq(0)
|
||||||
|
m.d.sync += rx_r.eq(rx)
|
||||||
|
with m.If(~rx_busy):
|
||||||
|
with m.If(~rx & rx_r): # look for start bit
|
||||||
|
m.d.sync += rx_busy.eq(1)
|
||||||
|
m.d.sync += rx_bitcount.eq(0)
|
||||||
|
with m.Else():
|
||||||
|
with m.If(uart_clk_rxen):
|
||||||
|
m.d.sync += rx_bitcount.eq(rx_bitcount + 1)
|
||||||
|
with m.If(rx_bitcount == 0):
|
||||||
|
with m.If(rx): # verify start bit
|
||||||
|
m.d.sync += rx_busy.eq(0)
|
||||||
|
with m.Elif(rx_bitcount == 9):
|
||||||
|
m.d.sync += rx_busy.eq(0)
|
||||||
|
with m.If(rx): # verify stop bit
|
||||||
|
m.d.sync += rx_data.eq(rx_reg)
|
||||||
|
m.d.sync += rx_done.eq(1)
|
||||||
|
with m.Else():
|
||||||
|
m.d.sync += rx_reg.eq(Cat(rx_reg[1:], rx))
|
||||||
|
with m.If(rx_busy):
|
||||||
|
m.d.sync += Cat(phase_accumulator_rx, uart_clk_rxen).eq(phase_accumulator_rx + self.tuning_word)
|
||||||
|
with m.Else():
|
||||||
|
m.d.sync += Cat(phase_accumulator_rx, uart_clk_rxen).eq(2**31)
|
||||||
|
|
||||||
|
return m
|
||||||
|
|
||||||
|
|
||||||
|
class RS232TX:
|
||||||
|
def __init__(self, tuning_word):
|
||||||
|
self.tx = Signal(reset=1)
|
||||||
|
self.data = Signal(8)
|
||||||
|
self.stb = Signal()
|
||||||
|
self.ack = Signal()
|
||||||
|
self.tuning_word = tuning_word
|
||||||
|
|
||||||
|
def elaborate(self, platform):
|
||||||
|
m = Module()
|
||||||
|
|
||||||
|
uart_clk_txen = Signal()
|
||||||
|
phase_accumulator_tx = Signal(32)
|
||||||
|
|
||||||
|
tx_reg = Signal(8)
|
||||||
|
tx_bitcount = Signal(4)
|
||||||
|
tx_busy = Signal()
|
||||||
|
m.d.sync += self.ack.eq(0),
|
||||||
|
with m.If(self.stb & ~tx_busy & ~self.ack):
|
||||||
|
m.d.sync += tx_reg.eq(self.data)
|
||||||
|
m.d.sync += tx_bitcount.eq(0)
|
||||||
|
m.d.sync += tx_busy.eq(1)
|
||||||
|
m.d.sync += self.tx.eq(0)
|
||||||
|
with m.Elif(uart_clk_txen & tx_busy):
|
||||||
|
m.d.sync += tx_bitcount.eq(tx_bitcount + 1)
|
||||||
|
with m.If(tx_bitcount == 8):
|
||||||
|
m.d.sync += self.tx.eq(1)
|
||||||
|
with m.Elif(tx_bitcount == 9):
|
||||||
|
m.d.sync += self.tx.eq(1)
|
||||||
|
m.d.sync += tx_busy.eq(0)
|
||||||
|
m.d.sync += self.ack.eq(1),
|
||||||
|
with m.Else():
|
||||||
|
m.d.sync += self.tx.eq(tx_reg[0])
|
||||||
|
m.d.sync += tx_reg.eq(Cat(tx_reg[1:], 0))
|
||||||
|
with m.If(tx_busy):
|
||||||
|
m.d.sync += Cat(phase_accumulator_tx, uart_clk_txen).eq(phase_accumulator_tx + self.tuning_word)
|
||||||
|
with m.Else():
|
||||||
|
m.d.sync += Cat(phase_accumulator_tx, uart_clk_txen).eq(0)
|
||||||
|
|
||||||
|
return m
|
||||||
|
|
||||||
|
|
||||||
|
class Loopback:
|
||||||
|
def elaborate(self, platform):
|
||||||
|
m = Module()
|
||||||
|
tuning_word = 2**31
|
||||||
|
tx = RS232TX(tuning_word)
|
||||||
|
rx = RS232RX(tuning_word)
|
||||||
|
m.submodules += tx, rx
|
||||||
|
m.d.comb += rx.rx.eq(tx.tx)
|
||||||
|
m.d.comb += tx.data.eq(42)
|
||||||
|
m.d.comb += tx.stb.eq(1)
|
||||||
|
return m
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
uart = Loopback()
|
||||||
|
main(uart)
|
7
heavycomps/setup.py
Normal file
7
heavycomps/setup.py
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
from setuptools import setup, find_packages
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name="heavycomps",
|
||||||
|
install_requires=["nmigen"],
|
||||||
|
packages=find_packages()
|
||||||
|
)
|
Loading…
Reference in New Issue
Block a user