gateware: failed attempt to add my own peripheral to litex

moving to amaranth because it at least has API docs :(
This commit is contained in:
David Lenfesty 2023-01-10 20:30:00 -07:00
parent d46dcc4a43
commit a6673297d4
3 changed files with 117 additions and 0 deletions

14
gateware/led_gpio.py Normal file
View File

@ -0,0 +1,14 @@
from migen import *
from litex.soc.interconnect.csr import *
from pathlib import Path
class LedGpio(AutoCSR, Module):
def __init__(self, platform, led: Signal):
#source = Path(__file__).parent / "led_gpio.v"
#platform.add_source(source)
self.register = CSRStorage(8)
self.comb += led.eq(self.register.storage[0])

80
gateware/led_gpio.v Normal file
View File

@ -0,0 +1,80 @@
`default_nettype none
module led_gpio #(
parameter DATA_WIDTH = 32,
parameter ADR_WIDTH = 32,
parameter SEL_WIDTH = 4 // ???
) (
// Main signals
input wire clk,
input wire rst,
// verilator lint_off UNUSED
// ---- LiteX Wishbone interface
// Address
input wire [ADR_WIDTH-1:0] adr,
// Data input (write)
input wire [DATA_WIDTH-1:0] dat_w,
// Data output (read)
output reg [DATA_WIDTH-1:0] dat_r,
// What parts of data are valid?
input wire [SEL_WIDTH-1:0] sel,
// Start cycle
input wire cyc,
// Enables wishbone interface
input wire stb,
// Bus cycle finished
output reg ack,
// Is this cycle a read or write?
input wire we,
// Cycle type
input wire [2:0] cti,
// Burst type
input wire [1:0] bte,
// Asserted if cycle completes with error
output wire err,
// verilator lint_on UNUSED
// Output
output wire led
);
// Tracks if we have started a new wishbone cycle. This or similar is needed so we don't
// think we're handling multiple wishbone cycles inside one.
reg cycle_started;
reg led_state;
always @(posedge clk) begin
// Always reset the cycle started
cycle_started <= 0;
if (rst) begin
led_state <= 0;
end else begin
// TODO ADR checking
ack <= 0;
err <= 0; // We never have any bus errors
dat_r <= 0;
if (!cycle_started && stb && cyc) begin
cycle_started <= 1; // Start cycle to be reset next clock
ack <= 1; // We always acknowledge immediately, we only take one clock to process
if (we) begin
// Writes to LED, so we need to assign output
led_state <= dat_w[0];
end else begin
// We want reads to get LED status
dat_r <= 3;
end
end
end
end
always @(*) begin
led = !led_state;
end
endmodule
`default_nettype wire

View File

@ -15,11 +15,17 @@ from litex.soc.integration.builder import *
from litex.soc.interconnect.csr import * from litex.soc.interconnect.csr import *
from litex.soc.interconnect import wishbone
from litex.soc.integration.soc import SoCRegion
from litedram.modules import M12L64322A from litedram.modules import M12L64322A
from litedram.phy import GENSDRPHY, HalfRateGENSDRPHY from litedram.phy import GENSDRPHY, HalfRateGENSDRPHY
from liteeth.phy.ecp5rgmii import LiteEthPHYRGMII from liteeth.phy.ecp5rgmii import LiteEthPHYRGMII
# My hardware
import led_gpio
# Module to configure clocks and resets # Module to configure clocks and resets
class _CRG(Module): class _CRG(Module):
def __init__(self, platform, sys_clk_freq, use_internal_osc=False, with_usb_pll=False, with_video_pll=False, sdram_rate="1:1"): def __init__(self, platform, sys_clk_freq, use_internal_osc=False, with_usb_pll=False, with_video_pll=False, sdram_rate="1:1"):
@ -86,6 +92,10 @@ class _CRG(Module):
# SoC definition - this basically instantiates hardware # SoC definition - this basically instantiates hardware
class SoC(SoCCore): class SoC(SoCCore):
csr_peripherals = ["led_gpio"]
#csr_map_update(SoCCore.csr_map, csr_peripherals)
# While there are more configurations in what I'm basing this off of, I'm reducing it to # While there are more configurations in what I'm basing this off of, I'm reducing it to
# one supported config. # one supported config.
def __init__(self, **kwargs): def __init__(self, **kwargs):
@ -113,6 +123,19 @@ class SoC(SoCCore):
l2_cache_size = 8192, l2_cache_size = 8192,
) )
# LED blinky thing
#wb_interface = wishbone.Interface()
led = platform.request("user_led_n")
self.submodules.led_gpio = led_gpio.LedGpio(platform, led)
#wb_interface.connect_to_pads(led, mode="slave")
#self.add_memory_region("led_gpio", 0x8F000000, 0x1000, type="dawda")
#self.add_wb_slave(0x8F000000, wb_interface, 0x1000)
# vague attempt based on
#region = SoCRegion(origin=0x8F000000, size=0x1000, cached=False)
#self.bus.add_slave(name="led_gpio", slave=wb_interface, region=region)
# TODO ethernet # TODO ethernet