This compiles and runson the Arty A7-100
This commit is contained in:
parent
4e3df09bb8
commit
0cfa172a89
|
@ -8,9 +8,10 @@
|
|||
|
||||
DEVICETREE_GEN_DIR=.
|
||||
|
||||
all: build/digilent_arty/digilent_arty.bit arty.dtb# mmio.py
|
||||
all: build/digilent_arty/digilent_arty.bit arty.dtb
|
||||
|
||||
csr.json build/digilent_arty/digilent_arty.bit: soc.py
|
||||
cd rtl && make
|
||||
python3 soc.py
|
||||
|
||||
clean:
|
||||
|
@ -21,6 +22,3 @@ arty.dts: csr.json
|
|||
|
||||
arty.dtb: arty.dts
|
||||
dtc -O dtb -o arty.dtb arty.dts
|
||||
|
||||
#mmio.py: csr2mp.py csr.json
|
||||
# python3 csr2mp.py csr.json > mmio.py
|
||||
|
|
|
@ -3,10 +3,11 @@
|
|||
# For license terms, refer to the files in `doc/copying` in the Upsilon
|
||||
# source distribution.
|
||||
|
||||
#all: make_bram
|
||||
all: make_spi
|
||||
|
||||
make_spi:
|
||||
cd spi && make codegen
|
||||
|
||||
dummy:
|
||||
@echo empty
|
||||
|
||||
#make_bram:
|
||||
# cd bram && make codegen
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
* Commit 29102c00a82ffd08f1e0b3c9cbac1c95c17f573b
|
||||
* Derived from commit 29102c00a82ffd08f1e0b3c9cbac1c95c17f573b
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -2167,7 +2167,6 @@ module picorv32 #(
|
|||
`endif
|
||||
endmodule
|
||||
|
||||
`ifdef 0
|
||||
// This is a simple example implementation of PICORV32_REGS.
|
||||
// Use the PICORV32_REGS mechanism if you want to use custom
|
||||
// memory resources to implement the processor register file.
|
||||
|
@ -2316,9 +2315,7 @@ module picorv32_pcpi_mul #(
|
|||
end
|
||||
end
|
||||
endmodule
|
||||
`endif
|
||||
|
||||
`ifdef 0
|
||||
module picorv32_pcpi_fast_mul #(
|
||||
parameter EXTRA_MUL_FFS = 0,
|
||||
parameter EXTRA_INSN_FFS = 0,
|
||||
|
@ -2421,7 +2418,6 @@ endmodule
|
|||
* picorv32_pcpi_div
|
||||
***************************************************************/
|
||||
|
||||
`ifdef 0
|
||||
module picorv32_pcpi_div (
|
||||
input clk, resetn,
|
||||
|
||||
|
@ -2514,13 +2510,10 @@ module picorv32_pcpi_div (
|
|||
end
|
||||
endmodule
|
||||
|
||||
`endif
|
||||
|
||||
/***************************************************************
|
||||
* picorv32_axi
|
||||
***************************************************************/
|
||||
|
||||
`ifdef 0
|
||||
module picorv32_axi #(
|
||||
parameter [ 0:0] ENABLE_COUNTERS = 1,
|
||||
parameter [ 0:0] ENABLE_COUNTERS64 = 1,
|
||||
|
@ -2729,13 +2722,11 @@ module picorv32_axi #(
|
|||
.trace_data (trace_data)
|
||||
);
|
||||
endmodule
|
||||
`endif
|
||||
|
||||
/***************************************************************
|
||||
* picorv32_axi_adapter
|
||||
***************************************************************/
|
||||
|
||||
`ifdef 0
|
||||
module picorv32_axi_adapter (
|
||||
input clk, resetn,
|
||||
|
||||
|
@ -2814,7 +2805,6 @@ module picorv32_axi_adapter (
|
|||
end
|
||||
end
|
||||
endmodule
|
||||
`endif
|
||||
|
||||
/***************************************************************
|
||||
* picorv32_wb
|
||||
|
|
446
gateware/soc.py
446
gateware/soc.py
|
@ -108,76 +108,76 @@ io = [
|
|||
# ("test_clock", 0, Pins("P18"), IOStandard("LVCMOS33"))
|
||||
]
|
||||
|
||||
# class PreemptiveInterface(Module, AutoCSR):
|
||||
# """ A preemptive interface is a manually controlled Wishbone interface
|
||||
# that stands between multiple masters (potentially interconnects) and a
|
||||
# single slave. A master controls which master (or interconnect) has access
|
||||
# to the slave. This is to avoid bus contention by having multiple buses. """
|
||||
#
|
||||
# def __init__(self, masters_len, slave):
|
||||
# """
|
||||
# :param masters_len: The amount of buses accessing this slave. This number
|
||||
# must be greater than one.
|
||||
# :param slave: The slave device. This object must have an Interface object
|
||||
# accessable as ``bus``.
|
||||
# """
|
||||
#
|
||||
# assert masters_len > 1
|
||||
# self.buses = []
|
||||
# self.master_select = CSRStorage(masters_len, name='master_select', description='RW bitstring of which master interconnect to connect to')
|
||||
# self.slave = slave
|
||||
#
|
||||
# for i in range(masters_len):
|
||||
# # Add the slave interface each master interconnect sees.
|
||||
# self.buses.append(Interface(data_width=32, address_width=32, addressing="byte"))
|
||||
#
|
||||
# """
|
||||
# Construct a combinatorial case statement. In verilog, the if
|
||||
# statment would look like
|
||||
#
|
||||
# always @ (*) case (master_select)
|
||||
# 1: begin
|
||||
# // Bus assignments...
|
||||
# end
|
||||
# 2: begin
|
||||
# // Bus assignments...
|
||||
# end
|
||||
# // more cases:
|
||||
# default:
|
||||
# // assign everything to master 0
|
||||
# end
|
||||
#
|
||||
# The If statement in Migen (Python HDL) is an object with a method
|
||||
# called "ElseIf" and "Else", that return objects with the specified
|
||||
# case attached. Instead of directly writing an If statement into
|
||||
# the combinatorial block, the If statement is constructed in a
|
||||
# for loop.
|
||||
#
|
||||
# The "assign_for_case" function constructs the body of the If
|
||||
# statement. It assigns all output ports to avoid latches.
|
||||
# """
|
||||
#
|
||||
# def assign_for_case(i):
|
||||
# asn = [ ]
|
||||
#
|
||||
# for j in range(masters_len):
|
||||
# asn += [
|
||||
# self.buses[i].cyc.eq(self.slave.bus.cyc if i == j else 0),
|
||||
# self.buses[i].stb.eq(self.slave.bus.stb if i == j else 0),
|
||||
# self.buses[i].we.eq(self.slave.bus.we if i == j else 0),
|
||||
# self.buses[i].sel.eq(self.slave.bus.sel if i == j else 0),
|
||||
# self.buses[i].adr.eq(self.slave.bus.adr if i == j else 0),
|
||||
# self.buses[i].dat_w.eq(self.slave.bus.dat_w if i == j else 0),
|
||||
# self.buses[i].ack.eq(self.slave.bus.ack if i == j else 0),
|
||||
# self.buses[i].dat_r.eq(self.slave.bus.dat_r if i == j else 0),
|
||||
# ]
|
||||
# return asn
|
||||
#
|
||||
# cases = {"default": assign_for_case(0)}
|
||||
# for i in range(1, masters_len):
|
||||
# cases[i] = assign_for_case(i)
|
||||
#
|
||||
# self.comb += Case(self.master_select.storage, cases)
|
||||
class PreemptiveInterface(Module, AutoCSR):
|
||||
""" A preemptive interface is a manually controlled Wishbone interface
|
||||
that stands between multiple masters (potentially interconnects) and a
|
||||
single slave. A master controls which master (or interconnect) has access
|
||||
to the slave. This is to avoid bus contention by having multiple buses. """
|
||||
|
||||
def __init__(self, masters_len, slave):
|
||||
"""
|
||||
:param masters_len: The amount of buses accessing this slave. This number
|
||||
must be greater than one.
|
||||
:param slave: The slave device. This object must have an Interface object
|
||||
accessable as ``bus``.
|
||||
"""
|
||||
|
||||
assert masters_len > 1
|
||||
self.buses = []
|
||||
self.master_select = CSRStorage(masters_len, name='master_select', description='RW bitstring of which master interconnect to connect to')
|
||||
self.slave = slave
|
||||
|
||||
for i in range(masters_len):
|
||||
# Add the slave interface each master interconnect sees.
|
||||
self.buses.append(Interface(data_width=32, address_width=32, addressing="byte"))
|
||||
|
||||
"""
|
||||
Construct a combinatorial case statement. In verilog, the if
|
||||
statment would look like
|
||||
|
||||
always @ (*) case (master_select)
|
||||
1: begin
|
||||
// Bus assignments...
|
||||
end
|
||||
2: begin
|
||||
// Bus assignments...
|
||||
end
|
||||
// more cases:
|
||||
default:
|
||||
// assign everything to master 0
|
||||
end
|
||||
|
||||
The If statement in Migen (Python HDL) is an object with a method
|
||||
called "ElseIf" and "Else", that return objects with the specified
|
||||
case attached. Instead of directly writing an If statement into
|
||||
the combinatorial block, the If statement is constructed in a
|
||||
for loop.
|
||||
|
||||
The "assign_for_case" function constructs the body of the If
|
||||
statement. It assigns all output ports to avoid latches.
|
||||
"""
|
||||
|
||||
def assign_for_case(i):
|
||||
asn = [ ]
|
||||
|
||||
for j in range(masters_len):
|
||||
asn += [
|
||||
self.buses[i].cyc.eq(self.slave.bus.cyc if i == j else 0),
|
||||
self.buses[i].stb.eq(self.slave.bus.stb if i == j else 0),
|
||||
self.buses[i].we.eq(self.slave.bus.we if i == j else 0),
|
||||
self.buses[i].sel.eq(self.slave.bus.sel if i == j else 0),
|
||||
self.buses[i].adr.eq(self.slave.bus.adr if i == j else 0),
|
||||
self.buses[i].dat_w.eq(self.slave.bus.dat_w if i == j else 0),
|
||||
self.buses[i].ack.eq(self.slave.bus.ack if i == j else 0),
|
||||
self.buses[i].dat_r.eq(self.slave.bus.dat_r if i == j else 0),
|
||||
]
|
||||
return asn
|
||||
|
||||
cases = {"default": assign_for_case(0)}
|
||||
for i in range(1, masters_len):
|
||||
cases[i] = assign_for_case(i)
|
||||
|
||||
self.comb += Case(self.master_select.storage, cases)
|
||||
|
||||
class SPIMaster(Module):
|
||||
def __init__(self, rst, miso, mosi, sck, ss,
|
||||
|
@ -226,151 +226,151 @@ class SPIMaster(Module):
|
|||
o_wb_dat_r = self.bus.dat_r,
|
||||
)
|
||||
|
||||
# TODO: Generalize CSR stuff
|
||||
# class ControlLoopParameters(Module, AutoCSR):
|
||||
# def __init__(self):
|
||||
# self.cl_I = CSRStorage(32, description='Integral parameter')
|
||||
# self.cl_P = CSRStorage(32, description='Proportional parameter')
|
||||
# self.deltaT = CSRStorage(32, description='Wait parameter')
|
||||
# self.setpt = CSRStorage(32, description='Setpoint')
|
||||
# self.zset = CSRStatus(32, description='Set Z position')
|
||||
# self.zpos = CSRStatus(32, description='Measured Z position')
|
||||
#
|
||||
# self.bus = Interface(data_width = 32, address_width = 32, addressing="word")
|
||||
# self.region = SoCRegion(size=minbits(0x17), cached=False)
|
||||
# self.sync += [
|
||||
# If(self.bus.cyc == 1 and self.bus.stb == 1 and self.bus.ack == 0,
|
||||
# Case(self.bus.adr[0:4], {
|
||||
# 0x0: self.bus.dat_r.eq(self.cl_I.storage),
|
||||
# 0x4: self.bus.dat_r.eq(self.cl_P.storage),
|
||||
# 0x8: self.bus.dat_r.eq(self.deltaT.storage),
|
||||
# 0xC: self.bus.dat_r.eq(self.setpt.storage),
|
||||
# 0x10: If(self.bus.we,
|
||||
# self.zset.status.eq(self.bus.dat_w)
|
||||
# ).Else(
|
||||
# self.bus.dat_r.eq(self.zset.status)
|
||||
# ),
|
||||
# 0x14: If(self.bus.we,
|
||||
# self.zpos.status.eq(self.bus.dat_w),
|
||||
# ).Else(
|
||||
# self.bus.dat_r.eq(self.zpos.status)
|
||||
# ),
|
||||
# }),
|
||||
# self.bus.ack.eq(1),
|
||||
# ).Else(
|
||||
# self.bus.ack.eq(0),
|
||||
# )
|
||||
# ]
|
||||
#
|
||||
# class BRAM(Module):
|
||||
# """ A BRAM (block ram) is a memory store that is completely separate from
|
||||
# the system RAM. They are much smaller.
|
||||
# """
|
||||
# def __init__(self, addr_mask, origin=None):
|
||||
# """
|
||||
# :param addr_mask: Mask which defines the amount of bytes accessable
|
||||
# by the BRAM.
|
||||
# :param origin: Origin of the BRAM module region. This is seen by the
|
||||
# subordinate master, not the usual master.
|
||||
# """
|
||||
# self.bus = Interface(data_width=32, address_width=32, addressing="byte")
|
||||
#
|
||||
# # Non-IO (i.e. MMIO) regions need to be cached
|
||||
# self.region = SoCRegion(origin=origin, size=addr_mask+1, cached=True)
|
||||
#
|
||||
# self.specials += Instance("bram",
|
||||
# p_ADDR_MASK = addr_mask,
|
||||
# i_clk = ClockSignal(),
|
||||
# i_wb_cyc = self.bus.cyc,
|
||||
# i_wb_stb = self.bus.stb,
|
||||
# i_wb_we = self.bus.we,
|
||||
# i_wb_sel = self.bus.sel,
|
||||
# i_wb_addr = self.bus.adr,
|
||||
# i_wb_dat_w = self.bus.dat_w,
|
||||
# o_wb_ack = self.bus.ack,
|
||||
# o_wb_dat_r = self.bus.dat_r,
|
||||
# )
|
||||
#
|
||||
# class PicoRV32(Module, AutoCSR):
|
||||
# def __init__(self, bramwid=0x1000):
|
||||
# self.submodules.params = params = ControlLoopParameters()
|
||||
# self.submodules.bram = self.bram = bram = BRAM(bramwid-1, origin=0x10000)
|
||||
# self.submodules.bram_iface = self.bram_iface = bram_iface = PreemptiveInterface(2, bram)
|
||||
#
|
||||
# # This is the PicoRV32 master
|
||||
# self.masterbus = Interface(data_width=32, address_width=32, addressing="byte")
|
||||
#
|
||||
# self.resetpin = CSRStorage(1, name="picorv32_reset", description="PicoRV32 reset")
|
||||
# self.trap = CSRStatus(1, name="picorv32_trap", description="Trap bit")
|
||||
#
|
||||
# self.ic = ic = SoCBusHandler(
|
||||
# standard="wishbone",
|
||||
# data_width=32,
|
||||
# address_width=32,
|
||||
# timeout=1e6,
|
||||
# bursting=False,
|
||||
# interconnect="shared",
|
||||
# interconnect_register=True,
|
||||
# reserved_regions={
|
||||
# "picorv32_null_region": SoCRegion(origin=0,size=0x10000, mode="ro", cached=True),
|
||||
# "picorv32_io": SoCIORegion(origin=0x100000, size=0x100, mode="rw", cached=False),
|
||||
# },
|
||||
# )
|
||||
#
|
||||
# ic.add_slave("picorv32_bram", bram_iface.buses[1], bram.region)
|
||||
# ic.add_slave("picorv32_params", params.bus, params.region)
|
||||
# ic.add_master("picorv32_master", self.masterbus)
|
||||
#
|
||||
# # NOTE: need to compile to these extact instructions
|
||||
# self.specials += Instance("picorv32_wb",
|
||||
# p_COMPRESSED_ISA = 1,
|
||||
# p_ENABLE_MUL = 1,
|
||||
# p_PROGADDR_RESET=0x10000,
|
||||
# p_PROGADDR_IRQ=0x100010,
|
||||
# p_REGS_INIT_ZERO = 1,
|
||||
# o_trap = self.trap.status,
|
||||
#
|
||||
# i_wb_rst_i = ~self.resetpin.storage,
|
||||
# i_wb_clk_i = ClockSignal(),
|
||||
# o_wbm_adr_o = self.masterbus.adr,
|
||||
# o_wbm_dat_o = self.masterbus.dat_r,
|
||||
# i_wbm_dat_i = self.masterbus.dat_w,
|
||||
# o_wbm_we_o = self.masterbus.we,
|
||||
# o_wbm_sel_o = self.masterbus.sel,
|
||||
# o_wbm_stb_o = self.masterbus.stb,
|
||||
# i_wbm_ack_i = self.masterbus.ack,
|
||||
# o_wbm_cyc_o = self.masterbus.cyc,
|
||||
#
|
||||
# o_pcpi_valid = Signal(),
|
||||
# o_pcpi_insn = Signal(32),
|
||||
# o_pcpi_rs1 = Signal(32),
|
||||
# o_pcpi_rs2 = Signal(32),
|
||||
# i_pcpi_wr = 0,
|
||||
# i_pcpi_wait = 0,
|
||||
# i_pcpi_rd = 0,
|
||||
# i_pcpi_ready = 0,
|
||||
#
|
||||
# i_irq = 0,
|
||||
# o_eoi = Signal(32),
|
||||
#
|
||||
# o_trace_valid = Signal(),
|
||||
# o_trace_data = Signal(36),
|
||||
# )
|
||||
#
|
||||
# def do_finalize(self):
|
||||
# self.ic.finalize()
|
||||
# jsondata = {}
|
||||
#
|
||||
# for region in self.ic.regions:
|
||||
# d = self.ic.regions[region]
|
||||
# jsondata[region] = {
|
||||
# "origin": d.origin,
|
||||
# "size": d.size,
|
||||
# }
|
||||
#
|
||||
# with open('picorv32.json', 'w') as f:
|
||||
# import json
|
||||
# json.dump(jsondata, f)
|
||||
#TODO: Generalize CSR stuff
|
||||
class ControlLoopParameters(Module, AutoCSR):
|
||||
def __init__(self):
|
||||
self.cl_I = CSRStorage(32, description='Integral parameter')
|
||||
self.cl_P = CSRStorage(32, description='Proportional parameter')
|
||||
self.deltaT = CSRStorage(32, description='Wait parameter')
|
||||
self.setpt = CSRStorage(32, description='Setpoint')
|
||||
self.zset = CSRStatus(32, description='Set Z position')
|
||||
self.zpos = CSRStatus(32, description='Measured Z position')
|
||||
|
||||
self.bus = Interface(data_width = 32, address_width = 32, addressing="word")
|
||||
self.region = SoCRegion(size=minbits(0x17), cached=False)
|
||||
self.sync += [
|
||||
If(self.bus.cyc == 1 and self.bus.stb == 1 and self.bus.ack == 0,
|
||||
Case(self.bus.adr[0:4], {
|
||||
0x0: self.bus.dat_r.eq(self.cl_I.storage),
|
||||
0x4: self.bus.dat_r.eq(self.cl_P.storage),
|
||||
0x8: self.bus.dat_r.eq(self.deltaT.storage),
|
||||
0xC: self.bus.dat_r.eq(self.setpt.storage),
|
||||
0x10: If(self.bus.we,
|
||||
self.zset.status.eq(self.bus.dat_w)
|
||||
).Else(
|
||||
self.bus.dat_r.eq(self.zset.status)
|
||||
),
|
||||
0x14: If(self.bus.we,
|
||||
self.zpos.status.eq(self.bus.dat_w),
|
||||
).Else(
|
||||
self.bus.dat_r.eq(self.zpos.status)
|
||||
),
|
||||
}),
|
||||
self.bus.ack.eq(1),
|
||||
).Else(
|
||||
self.bus.ack.eq(0),
|
||||
)
|
||||
]
|
||||
|
||||
class BRAM(Module):
|
||||
""" A BRAM (block ram) is a memory store that is completely separate from
|
||||
the system RAM. They are much smaller.
|
||||
"""
|
||||
def __init__(self, addr_mask, origin=None):
|
||||
"""
|
||||
:param addr_mask: Mask which defines the amount of bytes accessable
|
||||
by the BRAM.
|
||||
:param origin: Origin of the BRAM module region. This is seen by the
|
||||
subordinate master, not the usual master.
|
||||
"""
|
||||
self.bus = Interface(data_width=32, address_width=32, addressing="byte")
|
||||
|
||||
# Non-IO (i.e. MMIO) regions need to be cached
|
||||
self.region = SoCRegion(origin=origin, size=addr_mask+1, cached=True)
|
||||
|
||||
self.specials += Instance("bram",
|
||||
p_ADDR_MASK = addr_mask,
|
||||
i_clk = ClockSignal(),
|
||||
i_wb_cyc = self.bus.cyc,
|
||||
i_wb_stb = self.bus.stb,
|
||||
i_wb_we = self.bus.we,
|
||||
i_wb_sel = self.bus.sel,
|
||||
i_wb_addr = self.bus.adr,
|
||||
i_wb_dat_w = self.bus.dat_w,
|
||||
o_wb_ack = self.bus.ack,
|
||||
o_wb_dat_r = self.bus.dat_r,
|
||||
)
|
||||
|
||||
class PicoRV32(Module, AutoCSR):
|
||||
def __init__(self, bramwid=0x1000):
|
||||
self.submodules.params = params = ControlLoopParameters()
|
||||
self.submodules.bram = self.bram = bram = BRAM(bramwid-1, origin=0x10000)
|
||||
self.submodules.bram_iface = self.bram_iface = bram_iface = PreemptiveInterface(2, bram)
|
||||
|
||||
# This is the PicoRV32 master
|
||||
self.masterbus = Interface(data_width=32, address_width=32, addressing="byte")
|
||||
|
||||
self.resetpin = CSRStorage(1, name="picorv32_reset", description="PicoRV32 reset")
|
||||
self.trap = CSRStatus(1, name="picorv32_trap", description="Trap bit")
|
||||
|
||||
self.ic = ic = SoCBusHandler(
|
||||
standard="wishbone",
|
||||
data_width=32,
|
||||
address_width=32,
|
||||
timeout=1e6,
|
||||
bursting=False,
|
||||
interconnect="shared",
|
||||
interconnect_register=True,
|
||||
reserved_regions={
|
||||
"picorv32_null_region": SoCRegion(origin=0,size=0x10000, mode="ro", cached=True),
|
||||
"picorv32_io": SoCIORegion(origin=0x100000, size=0x100, mode="rw", cached=False),
|
||||
},
|
||||
)
|
||||
|
||||
ic.add_slave("picorv32_bram", bram_iface.buses[1], bram.region)
|
||||
ic.add_slave("picorv32_params", params.bus, params.region)
|
||||
ic.add_master("picorv32_master", self.masterbus)
|
||||
|
||||
# NOTE: need to compile to these extact instructions
|
||||
self.specials += Instance("picorv32_wb",
|
||||
p_COMPRESSED_ISA = 1,
|
||||
p_ENABLE_MUL = 1,
|
||||
p_PROGADDR_RESET=0x10000,
|
||||
p_PROGADDR_IRQ=0x100010,
|
||||
p_REGS_INIT_ZERO = 1,
|
||||
o_trap = self.trap.status,
|
||||
|
||||
i_wb_rst_i = ~self.resetpin.storage,
|
||||
i_wb_clk_i = ClockSignal(),
|
||||
o_wbm_adr_o = self.masterbus.adr,
|
||||
o_wbm_dat_o = self.masterbus.dat_r,
|
||||
i_wbm_dat_i = self.masterbus.dat_w,
|
||||
o_wbm_we_o = self.masterbus.we,
|
||||
o_wbm_sel_o = self.masterbus.sel,
|
||||
o_wbm_stb_o = self.masterbus.stb,
|
||||
i_wbm_ack_i = self.masterbus.ack,
|
||||
o_wbm_cyc_o = self.masterbus.cyc,
|
||||
|
||||
o_pcpi_valid = Signal(),
|
||||
o_pcpi_insn = Signal(32),
|
||||
o_pcpi_rs1 = Signal(32),
|
||||
o_pcpi_rs2 = Signal(32),
|
||||
i_pcpi_wr = 0,
|
||||
i_pcpi_wait = 0,
|
||||
i_pcpi_rd = 0,
|
||||
i_pcpi_ready = 0,
|
||||
|
||||
i_irq = 0,
|
||||
o_eoi = Signal(32),
|
||||
|
||||
o_trace_valid = Signal(),
|
||||
o_trace_data = Signal(36),
|
||||
)
|
||||
|
||||
def do_finalize(self):
|
||||
self.ic.finalize()
|
||||
jsondata = {}
|
||||
|
||||
for region in self.ic.regions:
|
||||
d = self.ic.regions[region]
|
||||
jsondata[region] = {
|
||||
"origin": d.origin,
|
||||
"size": d.size,
|
||||
}
|
||||
|
||||
with open('picorv32.json', 'w') as f:
|
||||
import json
|
||||
json.dump(jsondata, f)
|
||||
|
||||
# Clock and Reset Generator
|
||||
# I don't know how this works, I only know that it does.
|
||||
|
@ -441,11 +441,11 @@ class UpsilonSoC(SoCCore):
|
|||
Since Yosys doesn't support modern Verilog, only put preprocessed
|
||||
(if applicable) files here.
|
||||
"""
|
||||
#platform.add_source("rtl/picorv32/picorv32.v")
|
||||
#platform.add_source("rtl/spi/spi_master.v")
|
||||
#platform.add_source("rtl/spi/spi_master_ss.v")
|
||||
#platform.add_source("rtl/spi/spi_master_ss_wb.v")
|
||||
#platform.add_source("rtl/bram/bram.v")
|
||||
platform.add_source("rtl/picorv32/picorv32.v")
|
||||
platform.add_source("rtl/spi/spi_master_preprocessed.v")
|
||||
platform.add_source("rtl/spi/spi_master_ss.v")
|
||||
platform.add_source("rtl/spi/spi_master_ss_wb.v")
|
||||
platform.add_source("rtl/bram/bram.v")
|
||||
|
||||
# SoCCore does not have sane defaults (no integrated rom)
|
||||
SoCCore.__init__(self,
|
||||
|
@ -503,12 +503,12 @@ class UpsilonSoC(SoCCore):
|
|||
)
|
||||
self.bus.add_slave("spi0", self.spi0.bus, self.spi0.region)
|
||||
|
||||
#self.add_bram()
|
||||
#self.add_picorv32()
|
||||
self.add_bram()
|
||||
self.add_picorv32()
|
||||
|
||||
def main():
|
||||
""" Add modifications to SoC variables here """
|
||||
soc =UpsilonSoC(variant="a7-35")
|
||||
soc =UpsilonSoC(variant="a7-100")
|
||||
builder = Builder(soc, csr_json="csr.json", compile_software=True)
|
||||
builder.build()
|
||||
|
||||
|
|
Loading…
Reference in New Issue