From: Florent Kermarrec Date: Sat, 2 May 2015 09:14:55 +0000 (+0200) Subject: cores: avoid having too much directories when possible (for simple cores or cores... X-Git-Tag: 24jan2021_ls180~2272 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a4617014f4cb55cef70aac214970be39ab792a4c;p=litex.git cores: avoid having too much directories when possible (for simple cores or cores contained in a single file) --- diff --git a/misoclib/com/gpio.py b/misoclib/com/gpio.py new file mode 100644 index 00000000..88a49040 --- /dev/null +++ b/misoclib/com/gpio.py @@ -0,0 +1,31 @@ +from migen.fhdl.std import * +from migen.genlib.cdc import MultiReg +from migen.bank.description import * + + +class GPIOIn(Module, AutoCSR): + def __init__(self, signal): + self._in = CSRStatus(flen(signal)) + self.specials += MultiReg(signal, self._in.status) + + +class GPIOOut(Module, AutoCSR): + def __init__(self, signal): + self._out = CSRStorage(flen(signal)) + self.comb += signal.eq(self._out.storage) + + +class GPIOInOut(Module): + def __init__(self, in_signal, out_signal): + self.submodules.gpio_in = GPIOIn(in_signal) + self.submodules.gpio_out = GPIOOut(out_signal) + + def get_csrs(self): + return self.gpio_in.get_csrs() + self.gpio_out.get_csrs() + + +class Blinker(Module): + def __init__(self, signal, divbits=26): + counter = Signal(divbits) + self.comb += signal.eq(counter[divbits-1]) + self.sync += counter.eq(counter + 1) diff --git a/misoclib/com/gpio/__init__.py b/misoclib/com/gpio/__init__.py deleted file mode 100644 index 88a49040..00000000 --- a/misoclib/com/gpio/__init__.py +++ /dev/null @@ -1,31 +0,0 @@ -from migen.fhdl.std import * -from migen.genlib.cdc import MultiReg -from migen.bank.description import * - - -class GPIOIn(Module, AutoCSR): - def __init__(self, signal): - self._in = CSRStatus(flen(signal)) - self.specials += MultiReg(signal, self._in.status) - - -class GPIOOut(Module, AutoCSR): - def __init__(self, signal): - self._out = CSRStorage(flen(signal)) - self.comb += signal.eq(self._out.storage) - - -class GPIOInOut(Module): - def __init__(self, in_signal, out_signal): - self.submodules.gpio_in = GPIOIn(in_signal) - self.submodules.gpio_out = GPIOOut(out_signal) - - def get_csrs(self): - return self.gpio_in.get_csrs() + self.gpio_out.get_csrs() - - -class Blinker(Module): - def __init__(self, signal, divbits=26): - counter = Signal(divbits) - self.comb += signal.eq(counter[divbits-1]) - self.sync += counter.eq(counter + 1) diff --git a/misoclib/com/liteeth/example_designs/targets/tty.py b/misoclib/com/liteeth/example_designs/targets/tty.py index a05fee00..fc513302 100644 --- a/misoclib/com/liteeth/example_designs/targets/tty.py +++ b/misoclib/com/liteeth/example_designs/targets/tty.py @@ -3,7 +3,6 @@ from misoclib.tools.litescope.frontend.la import LiteScopeLA from misoclib.tools.litescope.core.port import LiteScopeTerm from misoclib.com.liteeth.common import * -from misoclib.com.liteeth.generic import * from targets.base import BaseSoC from misoclib.com.liteeth.frontend.tty import LiteEthTTY diff --git a/misoclib/com/liteeth/frontend/tty.py b/misoclib/com/liteeth/frontend/tty.py new file mode 100644 index 00000000..56867af9 --- /dev/null +++ b/misoclib/com/liteeth/frontend/tty.py @@ -0,0 +1,103 @@ +from misoclib.com.liteeth.common import * + + +class LiteEthTTYTX(Module): + def __init__(self, ip_address, udp_port, fifo_depth=None): + self.sink = sink = Sink(eth_tty_description(8)) + self.source = source = Source(eth_udp_user_description(8)) + + # # # + + if fifo_depth is None: + self.comb += [ + source.stb.eq(sink.stb), + source.sop.eq(1), + source.eop.eq(1), + source.length.eq(1), + source.data.eq(sink.data), + sink.ack.eq(source.ack) + ] + else: + self.submodules.fifo = fifo = SyncFIFO([("data", 8)], fifo_depth) + self.comb += Record.connect(sink, fifo.sink) + + self.submodules.level = level = FlipFlop(max=fifo_depth) + self.comb += level.d.eq(fifo.fifo.level) + + self.submodules.counter = counter = Counter(max=fifo_depth) + + self.submodules.fsm = fsm = FSM(reset_state="IDLE") + fsm.act("IDLE", + If(fifo.source.stb, + level.ce.eq(1), + counter.reset.eq(1), + NextState("SEND") + ) + ) + fsm.act("SEND", + source.stb.eq(fifo.source.stb), + source.sop.eq(counter.value == 0), + If(level.q == 0, + source.eop.eq(1), + ).Else( + source.eop.eq(counter.value == (level.q-1)), + ), + source.src_port.eq(udp_port), + source.dst_port.eq(udp_port), + source.ip_address.eq(ip_address), + If(level.q == 0, + source.length.eq(1), + ).Else( + source.length.eq(level.q), + ), + source.data.eq(fifo.source.data), + fifo.source.ack.eq(source.ack), + If(source.stb & source.ack, + counter.ce.eq(1), + If(source.eop, + NextState("IDLE") + ) + ) + ) + + +class LiteEthTTYRX(Module): + def __init__(self, ip_address, udp_port, fifo_depth=None): + self.sink = sink = Sink(eth_udp_user_description(8)) + self.source = source = Source(eth_tty_description(8)) + + # # # + + valid = Signal() + self.comb += valid.eq( + (sink.ip_address == ip_address) & + (sink.dst_port == udp_port) + ) + if fifo_depth is None: + self.comb += [ + source.stb.eq(sink.stb & valid), + source.data.eq(sink.data), + sink.ack.eq(source.ack) + ] + else: + self.submodules.fifo = fifo = SyncFIFO([("data", 8)], fifo_depth) + self.comb += [ + fifo.sink.stb.eq(sink.stb & valid), + fifo.sink.data.eq(sink.data), + sink.ack.eq(fifo.sink.ack), + Record.connect(fifo.source, source) + ] + + +class LiteEthTTY(Module): + def __init__(self, udp, ip_address, udp_port, + rx_fifo_depth=64, + tx_fifo_depth=64): + self.submodules.tx = tx = LiteEthTTYTX(ip_address, udp_port, tx_fifo_depth) + self.submodules.rx = rx = LiteEthTTYRX(ip_address, udp_port, rx_fifo_depth) + udp_port = udp.crossbar.get_port(udp_port, dw=8) + self.comb += [ + Record.connect(tx.source, udp_port.sink), + Record.connect(udp_port.source, rx.sink) + ] + self.sink, self.source = self.tx.sink, self.rx.source diff --git a/misoclib/com/liteeth/frontend/tty/__init__.py b/misoclib/com/liteeth/frontend/tty/__init__.py deleted file mode 100644 index 56867af9..00000000 --- a/misoclib/com/liteeth/frontend/tty/__init__.py +++ /dev/null @@ -1,103 +0,0 @@ -from misoclib.com.liteeth.common import * - - -class LiteEthTTYTX(Module): - def __init__(self, ip_address, udp_port, fifo_depth=None): - self.sink = sink = Sink(eth_tty_description(8)) - self.source = source = Source(eth_udp_user_description(8)) - - # # # - - if fifo_depth is None: - self.comb += [ - source.stb.eq(sink.stb), - source.sop.eq(1), - source.eop.eq(1), - source.length.eq(1), - source.data.eq(sink.data), - sink.ack.eq(source.ack) - ] - else: - self.submodules.fifo = fifo = SyncFIFO([("data", 8)], fifo_depth) - self.comb += Record.connect(sink, fifo.sink) - - self.submodules.level = level = FlipFlop(max=fifo_depth) - self.comb += level.d.eq(fifo.fifo.level) - - self.submodules.counter = counter = Counter(max=fifo_depth) - - self.submodules.fsm = fsm = FSM(reset_state="IDLE") - fsm.act("IDLE", - If(fifo.source.stb, - level.ce.eq(1), - counter.reset.eq(1), - NextState("SEND") - ) - ) - fsm.act("SEND", - source.stb.eq(fifo.source.stb), - source.sop.eq(counter.value == 0), - If(level.q == 0, - source.eop.eq(1), - ).Else( - source.eop.eq(counter.value == (level.q-1)), - ), - source.src_port.eq(udp_port), - source.dst_port.eq(udp_port), - source.ip_address.eq(ip_address), - If(level.q == 0, - source.length.eq(1), - ).Else( - source.length.eq(level.q), - ), - source.data.eq(fifo.source.data), - fifo.source.ack.eq(source.ack), - If(source.stb & source.ack, - counter.ce.eq(1), - If(source.eop, - NextState("IDLE") - ) - ) - ) - - -class LiteEthTTYRX(Module): - def __init__(self, ip_address, udp_port, fifo_depth=None): - self.sink = sink = Sink(eth_udp_user_description(8)) - self.source = source = Source(eth_tty_description(8)) - - # # # - - valid = Signal() - self.comb += valid.eq( - (sink.ip_address == ip_address) & - (sink.dst_port == udp_port) - ) - if fifo_depth is None: - self.comb += [ - source.stb.eq(sink.stb & valid), - source.data.eq(sink.data), - sink.ack.eq(source.ack) - ] - else: - self.submodules.fifo = fifo = SyncFIFO([("data", 8)], fifo_depth) - self.comb += [ - fifo.sink.stb.eq(sink.stb & valid), - fifo.sink.data.eq(sink.data), - sink.ack.eq(fifo.sink.ack), - Record.connect(fifo.source, source) - ] - - -class LiteEthTTY(Module): - def __init__(self, udp, ip_address, udp_port, - rx_fifo_depth=64, - tx_fifo_depth=64): - self.submodules.tx = tx = LiteEthTTYTX(ip_address, udp_port, tx_fifo_depth) - self.submodules.rx = rx = LiteEthTTYRX(ip_address, udp_port, rx_fifo_depth) - udp_port = udp.crossbar.get_port(udp_port, dw=8) - self.comb += [ - Record.connect(tx.source, udp_port.sink), - Record.connect(udp_port.source, rx.sink) - ] - self.sink, self.source = self.tx.sink, self.rx.source diff --git a/misoclib/cpu/git.py b/misoclib/cpu/git.py new file mode 100644 index 00000000..e92a6088 --- /dev/null +++ b/misoclib/cpu/git.py @@ -0,0 +1,6 @@ +import subprocess + + +def get_id(): + output = subprocess.check_output(["git", "rev-parse", "HEAD"]).decode("ascii") + return int(output[:8], 16) diff --git a/misoclib/cpu/identifier.py b/misoclib/cpu/identifier.py new file mode 100644 index 00000000..2c0d8211 --- /dev/null +++ b/misoclib/cpu/identifier.py @@ -0,0 +1,22 @@ +from migen.fhdl.std import * +from migen.bank.description import * + +from misoclib.cpu import git + + +class Identifier(Module, AutoCSR): + def __init__(self, sysid, frequency, revision=None): + self._sysid = CSRStatus(16) + self._revision = CSRStatus(32) + self._frequency = CSRStatus(32) + + ### + + if revision is None: + revision = git.get_id() + + self.comb += [ + self._sysid.status.eq(sysid), + self._revision.status.eq(revision), + self._frequency.status.eq(frequency) + ] diff --git a/misoclib/cpu/lm32.py b/misoclib/cpu/lm32.py new file mode 100644 index 00000000..8ea7637b --- /dev/null +++ b/misoclib/cpu/lm32.py @@ -0,0 +1,63 @@ +import os + +from migen.fhdl.std import * +from migen.bus import wishbone + + +class LM32(Module): + def __init__(self, platform, eba_reset): + self.ibus = i = wishbone.Interface() + self.dbus = d = wishbone.Interface() + self.interrupt = Signal(32) + + ### + + i_adr_o = Signal(32) + d_adr_o = Signal(32) + self.specials += Instance("lm32_cpu", + p_eba_reset=Instance.PreformattedParam("32'h{:08x}".format(eba_reset)), + + i_clk_i=ClockSignal(), + i_rst_i=ResetSignal(), + + i_interrupt=self.interrupt, + + o_I_ADR_O=i_adr_o, + o_I_DAT_O=i.dat_w, + o_I_SEL_O=i.sel, + o_I_CYC_O=i.cyc, + o_I_STB_O=i.stb, + o_I_WE_O=i.we, + o_I_CTI_O=i.cti, + o_I_BTE_O=i.bte, + i_I_DAT_I=i.dat_r, + i_I_ACK_I=i.ack, + i_I_ERR_I=i.err, + i_I_RTY_I=0, + + o_D_ADR_O=d_adr_o, + o_D_DAT_O=d.dat_w, + o_D_SEL_O=d.sel, + o_D_CYC_O=d.cyc, + o_D_STB_O=d.stb, + o_D_WE_O=d.we, + o_D_CTI_O=d.cti, + o_D_BTE_O=d.bte, + i_D_DAT_I=d.dat_r, + i_D_ACK_I=d.ack, + i_D_ERR_I=d.err, + i_D_RTY_I=0) + + self.comb += [ + self.ibus.adr.eq(i_adr_o[2:]), + self.dbus.adr.eq(d_adr_o[2:]) + ] + + # add Verilog sources + platform.add_sources(os.path.join("extcores", "lm32", "submodule", "rtl"), + "lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v", + "lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v", + "lm32_shifter.v", "lm32_multiplier.v", "lm32_mc_arithmetic.v", + "lm32_interrupt.v", "lm32_ram.v", "lm32_dp_ram.v", "lm32_icache.v", + "lm32_dcache.v", "lm32_debug.v", "lm32_itlb.v", "lm32_dtlb.v") + platform.add_verilog_include_path(os.path.join("extcores", "lm32")) diff --git a/misoclib/cpu/lm32/__init__.py b/misoclib/cpu/lm32/__init__.py deleted file mode 100644 index 8ea7637b..00000000 --- a/misoclib/cpu/lm32/__init__.py +++ /dev/null @@ -1,63 +0,0 @@ -import os - -from migen.fhdl.std import * -from migen.bus import wishbone - - -class LM32(Module): - def __init__(self, platform, eba_reset): - self.ibus = i = wishbone.Interface() - self.dbus = d = wishbone.Interface() - self.interrupt = Signal(32) - - ### - - i_adr_o = Signal(32) - d_adr_o = Signal(32) - self.specials += Instance("lm32_cpu", - p_eba_reset=Instance.PreformattedParam("32'h{:08x}".format(eba_reset)), - - i_clk_i=ClockSignal(), - i_rst_i=ResetSignal(), - - i_interrupt=self.interrupt, - - o_I_ADR_O=i_adr_o, - o_I_DAT_O=i.dat_w, - o_I_SEL_O=i.sel, - o_I_CYC_O=i.cyc, - o_I_STB_O=i.stb, - o_I_WE_O=i.we, - o_I_CTI_O=i.cti, - o_I_BTE_O=i.bte, - i_I_DAT_I=i.dat_r, - i_I_ACK_I=i.ack, - i_I_ERR_I=i.err, - i_I_RTY_I=0, - - o_D_ADR_O=d_adr_o, - o_D_DAT_O=d.dat_w, - o_D_SEL_O=d.sel, - o_D_CYC_O=d.cyc, - o_D_STB_O=d.stb, - o_D_WE_O=d.we, - o_D_CTI_O=d.cti, - o_D_BTE_O=d.bte, - i_D_DAT_I=d.dat_r, - i_D_ACK_I=d.ack, - i_D_ERR_I=d.err, - i_D_RTY_I=0) - - self.comb += [ - self.ibus.adr.eq(i_adr_o[2:]), - self.dbus.adr.eq(d_adr_o[2:]) - ] - - # add Verilog sources - platform.add_sources(os.path.join("extcores", "lm32", "submodule", "rtl"), - "lm32_cpu.v", "lm32_instruction_unit.v", "lm32_decoder.v", - "lm32_load_store_unit.v", "lm32_adder.v", "lm32_addsub.v", "lm32_logic_op.v", - "lm32_shifter.v", "lm32_multiplier.v", "lm32_mc_arithmetic.v", - "lm32_interrupt.v", "lm32_ram.v", "lm32_dp_ram.v", "lm32_icache.v", - "lm32_dcache.v", "lm32_debug.v", "lm32_itlb.v", "lm32_dtlb.v") - platform.add_verilog_include_path(os.path.join("extcores", "lm32")) diff --git a/misoclib/cpu/mor1kx.py b/misoclib/cpu/mor1kx.py new file mode 100644 index 00000000..4114c319 --- /dev/null +++ b/misoclib/cpu/mor1kx.py @@ -0,0 +1,80 @@ +import os + +from migen.fhdl.std import * +from migen.bus import wishbone + + +class MOR1KX(Module): + def __init__(self, platform, reset_pc): + self.ibus = i = wishbone.Interface() + self.dbus = d = wishbone.Interface() + self.interrupt = Signal(32) + + ### + + i_adr_o = Signal(32) + d_adr_o = Signal(32) + self.specials += Instance("mor1kx", + p_FEATURE_INSTRUCTIONCACHE="ENABLED", + p_OPTION_ICACHE_BLOCK_WIDTH=4, + p_OPTION_ICACHE_SET_WIDTH=8, + p_OPTION_ICACHE_WAYS=1, + p_OPTION_ICACHE_LIMIT_WIDTH=31, + p_FEATURE_DATACACHE="ENABLED", + p_OPTION_DCACHE_BLOCK_WIDTH=4, + p_OPTION_DCACHE_SET_WIDTH=8, + p_OPTION_DCACHE_WAYS=1, + p_OPTION_DCACHE_LIMIT_WIDTH=31, + p_FEATURE_TIMER="NONE", + p_OPTION_PIC_TRIGGER="LEVEL", + p_FEATURE_SYSCALL="NONE", + p_FEATURE_TRAP="NONE", + p_FEATURE_RANGE="NONE", + p_FEATURE_OVERFLOW="NONE", + p_FEATURE_ADDC="NONE", + p_FEATURE_CMOV="NONE", + p_FEATURE_FFL1="NONE", + p_OPTION_CPU0="CAPPUCCINO", + p_OPTION_RESET_PC=reset_pc, + p_IBUS_WB_TYPE="B3_REGISTERED_FEEDBACK", + p_DBUS_WB_TYPE="B3_REGISTERED_FEEDBACK", + + i_clk=ClockSignal(), + i_rst=ResetSignal(), + + i_irq_i=self.interrupt, + + o_iwbm_adr_o=i_adr_o, + o_iwbm_dat_o=i.dat_w, + o_iwbm_sel_o=i.sel, + o_iwbm_cyc_o=i.cyc, + o_iwbm_stb_o=i.stb, + o_iwbm_we_o=i.we, + o_iwbm_cti_o=i.cti, + o_iwbm_bte_o=i.bte, + i_iwbm_dat_i=i.dat_r, + i_iwbm_ack_i=i.ack, + i_iwbm_err_i=i.err, + i_iwbm_rty_i=0, + + o_dwbm_adr_o=d_adr_o, + o_dwbm_dat_o=d.dat_w, + o_dwbm_sel_o=d.sel, + o_dwbm_cyc_o=d.cyc, + o_dwbm_stb_o=d.stb, + o_dwbm_we_o=d.we, + o_dwbm_cti_o=d.cti, + o_dwbm_bte_o=d.bte, + i_dwbm_dat_i=d.dat_r, + i_dwbm_ack_i=d.ack, + i_dwbm_err_i=d.err, + i_dwbm_rty_i=0) + + self.comb += [ + self.ibus.adr.eq(i_adr_o[2:]), + self.dbus.adr.eq(d_adr_o[2:]) + ] + + # add Verilog sources + platform.add_source_dir(os.path.join("extcores", "mor1kx", "submodule", + "rtl", "verilog")) diff --git a/misoclib/cpu/mor1kx/__init__.py b/misoclib/cpu/mor1kx/__init__.py deleted file mode 100644 index 4114c319..00000000 --- a/misoclib/cpu/mor1kx/__init__.py +++ /dev/null @@ -1,80 +0,0 @@ -import os - -from migen.fhdl.std import * -from migen.bus import wishbone - - -class MOR1KX(Module): - def __init__(self, platform, reset_pc): - self.ibus = i = wishbone.Interface() - self.dbus = d = wishbone.Interface() - self.interrupt = Signal(32) - - ### - - i_adr_o = Signal(32) - d_adr_o = Signal(32) - self.specials += Instance("mor1kx", - p_FEATURE_INSTRUCTIONCACHE="ENABLED", - p_OPTION_ICACHE_BLOCK_WIDTH=4, - p_OPTION_ICACHE_SET_WIDTH=8, - p_OPTION_ICACHE_WAYS=1, - p_OPTION_ICACHE_LIMIT_WIDTH=31, - p_FEATURE_DATACACHE="ENABLED", - p_OPTION_DCACHE_BLOCK_WIDTH=4, - p_OPTION_DCACHE_SET_WIDTH=8, - p_OPTION_DCACHE_WAYS=1, - p_OPTION_DCACHE_LIMIT_WIDTH=31, - p_FEATURE_TIMER="NONE", - p_OPTION_PIC_TRIGGER="LEVEL", - p_FEATURE_SYSCALL="NONE", - p_FEATURE_TRAP="NONE", - p_FEATURE_RANGE="NONE", - p_FEATURE_OVERFLOW="NONE", - p_FEATURE_ADDC="NONE", - p_FEATURE_CMOV="NONE", - p_FEATURE_FFL1="NONE", - p_OPTION_CPU0="CAPPUCCINO", - p_OPTION_RESET_PC=reset_pc, - p_IBUS_WB_TYPE="B3_REGISTERED_FEEDBACK", - p_DBUS_WB_TYPE="B3_REGISTERED_FEEDBACK", - - i_clk=ClockSignal(), - i_rst=ResetSignal(), - - i_irq_i=self.interrupt, - - o_iwbm_adr_o=i_adr_o, - o_iwbm_dat_o=i.dat_w, - o_iwbm_sel_o=i.sel, - o_iwbm_cyc_o=i.cyc, - o_iwbm_stb_o=i.stb, - o_iwbm_we_o=i.we, - o_iwbm_cti_o=i.cti, - o_iwbm_bte_o=i.bte, - i_iwbm_dat_i=i.dat_r, - i_iwbm_ack_i=i.ack, - i_iwbm_err_i=i.err, - i_iwbm_rty_i=0, - - o_dwbm_adr_o=d_adr_o, - o_dwbm_dat_o=d.dat_w, - o_dwbm_sel_o=d.sel, - o_dwbm_cyc_o=d.cyc, - o_dwbm_stb_o=d.stb, - o_dwbm_we_o=d.we, - o_dwbm_cti_o=d.cti, - o_dwbm_bte_o=d.bte, - i_dwbm_dat_i=d.dat_r, - i_dwbm_ack_i=d.ack, - i_dwbm_err_i=d.err, - i_dwbm_rty_i=0) - - self.comb += [ - self.ibus.adr.eq(i_adr_o[2:]), - self.dbus.adr.eq(d_adr_o[2:]) - ] - - # add Verilog sources - platform.add_source_dir(os.path.join("extcores", "mor1kx", "submodule", - "rtl", "verilog")) diff --git a/misoclib/cpu/peripherals/__init__.py b/misoclib/cpu/peripherals/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/misoclib/cpu/peripherals/identifier/__init__.py b/misoclib/cpu/peripherals/identifier/__init__.py deleted file mode 100644 index fc21ed92..00000000 --- a/misoclib/cpu/peripherals/identifier/__init__.py +++ /dev/null @@ -1,22 +0,0 @@ -from migen.fhdl.std import * -from migen.bank.description import * - -from misoclib.cpu.peripherals.identifier import git - - -class Identifier(Module, AutoCSR): - def __init__(self, sysid, frequency, revision=None): - self._sysid = CSRStatus(16) - self._revision = CSRStatus(32) - self._frequency = CSRStatus(32) - - ### - - if revision is None: - revision = git.get_id() - - self.comb += [ - self._sysid.status.eq(sysid), - self._revision.status.eq(revision), - self._frequency.status.eq(frequency) - ] diff --git a/misoclib/cpu/peripherals/identifier/git.py b/misoclib/cpu/peripherals/identifier/git.py deleted file mode 100644 index e92a6088..00000000 --- a/misoclib/cpu/peripherals/identifier/git.py +++ /dev/null @@ -1,6 +0,0 @@ -import subprocess - - -def get_id(): - output = subprocess.check_output(["git", "rev-parse", "HEAD"]).decode("ascii") - return int(output[:8], 16) diff --git a/misoclib/cpu/peripherals/timer/__init__.py b/misoclib/cpu/peripherals/timer/__init__.py deleted file mode 100644 index 4061f837..00000000 --- a/misoclib/cpu/peripherals/timer/__init__.py +++ /dev/null @@ -1,34 +0,0 @@ -from migen.fhdl.std import * -from migen.bank.description import * -from migen.bank.eventmanager import * - - -class Timer(Module, AutoCSR): - def __init__(self, width=32): - self._load = CSRStorage(width) - self._reload = CSRStorage(width) - self._en = CSRStorage() - self._update_value = CSR() - self._value = CSRStatus(width) - - self.submodules.ev = EventManager() - self.ev.zero = EventSourceProcess() - self.ev.finalize() - - ### - - value = Signal(width) - self.sync += [ - If(self._en.storage, - If(value == 0, - # set reload to 0 to disable reloading - value.eq(self._reload.storage) - ).Else( - value.eq(value - 1) - ) - ).Else( - value.eq(self._load.storage) - ), - If(self._update_value.re, self._value.status.eq(value)) - ] - self.comb += self.ev.zero.trigger.eq(value != 0) diff --git a/misoclib/cpu/timer.py b/misoclib/cpu/timer.py new file mode 100644 index 00000000..4061f837 --- /dev/null +++ b/misoclib/cpu/timer.py @@ -0,0 +1,34 @@ +from migen.fhdl.std import * +from migen.bank.description import * +from migen.bank.eventmanager import * + + +class Timer(Module, AutoCSR): + def __init__(self, width=32): + self._load = CSRStorage(width) + self._reload = CSRStorage(width) + self._en = CSRStorage() + self._update_value = CSR() + self._value = CSRStatus(width) + + self.submodules.ev = EventManager() + self.ev.zero = EventSourceProcess() + self.ev.finalize() + + ### + + value = Signal(width) + self.sync += [ + If(self._en.storage, + If(value == 0, + # set reload to 0 to disable reloading + value.eq(self._reload.storage) + ).Else( + value.eq(value - 1) + ) + ).Else( + value.eq(self._load.storage) + ), + If(self._update_value.re, self._value.status.eq(value)) + ] + self.comb += self.ev.zero.trigger.eq(value != 0) diff --git a/misoclib/mem/flash/norflash16.py b/misoclib/mem/flash/norflash16.py new file mode 100644 index 00000000..42c68c07 --- /dev/null +++ b/misoclib/mem/flash/norflash16.py @@ -0,0 +1,103 @@ +from migen.fhdl.std import * +from migen.bus import wishbone +from migen.genlib.fsm import FSM, NextState + + +class NorFlash16(Module): + def __init__(self, pads, rd_timing, wr_timing): + self.bus = wishbone.Interface() + + ### + + data = TSTriple(16) + lsb = Signal() + + self.specials += data.get_tristate(pads.d) + self.comb += [ + data.oe.eq(pads.oe_n), + pads.ce_n.eq(0) + ] + + load_lo = Signal() + load_hi = Signal() + store = Signal() + + pads.oe_n.reset, pads.we_n.reset = 1, 1 + self.sync += [ + pads.oe_n.eq(1), + pads.we_n.eq(1), + + # Register data/address to avoid off-chip glitches + If(self.bus.cyc & self.bus.stb, + pads.adr.eq(Cat(lsb, self.bus.adr)), + If(self.bus.we, + # Only 16-bit writes are supported. Assume sel=0011 or 1100. + If(self.bus.sel[0], + data.o.eq(self.bus.dat_w[:16]) + ).Else( + data.o.eq(self.bus.dat_w[16:]) + ) + ).Else( + pads.oe_n.eq(0) + ) + ), + + If(load_lo, self.bus.dat_r[:16].eq(data.i)), + If(load_hi, self.bus.dat_r[16:].eq(data.i)), + If(store, pads.we_n.eq(0)) + ] + + # Typical timing of the flash chips: + # - 110ns address to output + # - 50ns write pulse width + counter = Signal(max=max(rd_timing, wr_timing)+1) + counter_en = Signal() + counter_wr_mode = Signal() + counter_done = Signal() + self.comb += counter_done.eq(counter == Mux(counter_wr_mode, wr_timing, rd_timing)) + self.sync += If(counter_en & ~counter_done, + counter.eq(counter + 1) + ).Else( + counter.eq(0) + ) + + fsm = FSM() + self.submodules += fsm + + fsm.act("IDLE", + If(self.bus.cyc & self.bus.stb, + If(self.bus.we, + NextState("WR") + ).Else( + NextState("RD_HI") + ) + ) + ) + fsm.act("RD_HI", + lsb.eq(0), + counter_en.eq(1), + If(counter_done, + load_hi.eq(1), + NextState("RD_LO") + ) + ) + fsm.act("RD_LO", + lsb.eq(1), + counter_en.eq(1), + If(counter_done, + load_lo.eq(1), + NextState("ACK") + ) + ) + fsm.act("WR", + # supported cases: sel=0011 [lsb=1] and sel=1100 [lsb=0] + lsb.eq(self.bus.sel[0]), + counter_wr_mode.eq(1), + counter_en.eq(1), + store.eq(1), + If(counter_done, NextState("ACK")) + ) + fsm.act("ACK", + self.bus.ack.eq(1), + NextState("IDLE") + ) diff --git a/misoclib/mem/flash/norflash16/__init__.py b/misoclib/mem/flash/norflash16/__init__.py deleted file mode 100644 index 42c68c07..00000000 --- a/misoclib/mem/flash/norflash16/__init__.py +++ /dev/null @@ -1,103 +0,0 @@ -from migen.fhdl.std import * -from migen.bus import wishbone -from migen.genlib.fsm import FSM, NextState - - -class NorFlash16(Module): - def __init__(self, pads, rd_timing, wr_timing): - self.bus = wishbone.Interface() - - ### - - data = TSTriple(16) - lsb = Signal() - - self.specials += data.get_tristate(pads.d) - self.comb += [ - data.oe.eq(pads.oe_n), - pads.ce_n.eq(0) - ] - - load_lo = Signal() - load_hi = Signal() - store = Signal() - - pads.oe_n.reset, pads.we_n.reset = 1, 1 - self.sync += [ - pads.oe_n.eq(1), - pads.we_n.eq(1), - - # Register data/address to avoid off-chip glitches - If(self.bus.cyc & self.bus.stb, - pads.adr.eq(Cat(lsb, self.bus.adr)), - If(self.bus.we, - # Only 16-bit writes are supported. Assume sel=0011 or 1100. - If(self.bus.sel[0], - data.o.eq(self.bus.dat_w[:16]) - ).Else( - data.o.eq(self.bus.dat_w[16:]) - ) - ).Else( - pads.oe_n.eq(0) - ) - ), - - If(load_lo, self.bus.dat_r[:16].eq(data.i)), - If(load_hi, self.bus.dat_r[16:].eq(data.i)), - If(store, pads.we_n.eq(0)) - ] - - # Typical timing of the flash chips: - # - 110ns address to output - # - 50ns write pulse width - counter = Signal(max=max(rd_timing, wr_timing)+1) - counter_en = Signal() - counter_wr_mode = Signal() - counter_done = Signal() - self.comb += counter_done.eq(counter == Mux(counter_wr_mode, wr_timing, rd_timing)) - self.sync += If(counter_en & ~counter_done, - counter.eq(counter + 1) - ).Else( - counter.eq(0) - ) - - fsm = FSM() - self.submodules += fsm - - fsm.act("IDLE", - If(self.bus.cyc & self.bus.stb, - If(self.bus.we, - NextState("WR") - ).Else( - NextState("RD_HI") - ) - ) - ) - fsm.act("RD_HI", - lsb.eq(0), - counter_en.eq(1), - If(counter_done, - load_hi.eq(1), - NextState("RD_LO") - ) - ) - fsm.act("RD_LO", - lsb.eq(1), - counter_en.eq(1), - If(counter_done, - load_lo.eq(1), - NextState("ACK") - ) - ) - fsm.act("WR", - # supported cases: sel=0011 [lsb=1] and sel=1100 [lsb=0] - lsb.eq(self.bus.sel[0]), - counter_wr_mode.eq(1), - counter_en.eq(1), - store.eq(1), - If(counter_done, NextState("ACK")) - ) - fsm.act("ACK", - self.bus.ack.eq(1), - NextState("IDLE") - ) diff --git a/misoclib/mem/flash/spiflash.py b/misoclib/mem/flash/spiflash.py new file mode 100644 index 00000000..f842bfdf --- /dev/null +++ b/misoclib/mem/flash/spiflash.py @@ -0,0 +1,181 @@ +from migen.fhdl.std import * +from migen.bus.transactions import * +from migen.bus import wishbone +from migen.genlib.misc import timeline +from migen.genlib.record import Record +from migen.bank.description import AutoCSR, CSRStorage, CSRStatus + +_FAST_READ = 0x0b +_DIOFR = 0xbb +_QIOFR = 0xeb + + +def _format_cmd(cmd, spi_width): + """ + `cmd` is the read instruction. Since everything is transmitted on all + dq lines (cmd, adr and data), extend/interleave cmd to full pads.dq + width even if dq1-dq3 are don't care during the command phase: + For example, for N25Q128, 0xeb is the quad i/o fast read, and + extended to 4 bits (dq1,dq2,dq3 high) is: 0xfffefeff + """ + c = 2**(8*spi_width)-1 + for b in range(8): + if not (cmd>>b)%2: + c &= ~(1<<(b*spi_width)) + return c + + +class SpiFlash(Module, AutoCSR): + def __init__(self, pads, dummy=15, div=2, with_bitbang=True): + """ + Simple SPI flash, e.g. N25Q128 on the LX9 Microboard. + + Supports multi-bit pseudo-parallel reads (aka Dual or Quad I/O Fast + Read). Only supports mode0 (cpol=0, cpha=0). + Optionally supports software bitbanging (for write, erase, or other commands). + """ + self.bus = bus = wishbone.Interface() + spi_width = flen(pads.dq) + if with_bitbang: + self.bitbang = CSRStorage(4) + self.miso = CSRStatus() + self.bitbang_en = CSRStorage() + + ### + + cs_n = Signal(reset=1) + clk = Signal() + dq_oe = Signal() + wbone_width = flen(bus.dat_r) + + + read_cmd_params = { + 4: (_format_cmd(_QIOFR, 4), 4*8), + 2: (_format_cmd(_DIOFR, 2), 2*8), + 1: (_format_cmd(_FAST_READ, 1), 1*8) + } + read_cmd, cmd_width = read_cmd_params[spi_width] + addr_width = 24 + + pads.cs_n.reset = 1 + + dq = TSTriple(spi_width) + self.specials.dq = dq.get_tristate(pads.dq) + + sr = Signal(max(cmd_width, addr_width, wbone_width)) + dqs = Replicate(1, spi_width-1) + + self.comb += bus.dat_r.eq(sr) + + hw_read_logic = [ + pads.clk.eq(clk), + pads.cs_n.eq(cs_n), + dq.o.eq(sr[-spi_width:]), + dq.oe.eq(dq_oe) + ] + + if with_bitbang: + bitbang_logic = [ + pads.clk.eq(self.bitbang.storage[1]), + pads.cs_n.eq(self.bitbang.storage[2]), + dq.o.eq(Cat(self.bitbang.storage[0], dqs)), + If(self.bitbang.storage[3], + dq.oe.eq(0) + ).Else( + dq.oe.eq(1) + ), + If(self.bitbang.storage[1], + self.miso.status.eq(dq.i[-1]) + ) + ] + + self.comb += \ + If(self.bitbang_en.storage, + bitbang_logic + ).Else( + hw_read_logic + ) + else: + self.comb += hw_read_logic + + if div < 2: + raise ValueError("Unsupported value \'{}\' for div parameter for SpiFlash core".format(div)) + else: + i = Signal(max=div) + dqi = Signal(spi_width) + self.sync += [ + If(i == div//2 - 1, + clk.eq(1), + dqi.eq(dq.i), + ), + If(i == div - 1, + i.eq(0), + clk.eq(0), + sr.eq(Cat(dqi, sr[:-spi_width])) + ).Else( + i.eq(i + 1), + ), + ] + + # spi is byte-addressed, prefix by zeros + z = Replicate(0, log2_int(wbone_width//8)) + + seq = [ + (cmd_width//spi_width*div, + [dq_oe.eq(1), cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]), + (addr_width//spi_width*div, + [sr[-addr_width:].eq(Cat(z, bus.adr))]), + ((dummy + wbone_width//spi_width)*div, + [dq_oe.eq(0)]), + (1, + [bus.ack.eq(1), cs_n.eq(1)]), + (div, # tSHSL! + [bus.ack.eq(0)]), + (0, + []), + ] + + # accumulate timeline deltas + t, tseq = 0, [] + for dt, a in seq: + tseq.append((t, a)) + t += dt + + self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq) + + +class SpiFlashTB(Module): + def __init__(self): + self.submodules.master = wishbone.Initiator(self.gen_reads()) + self.pads = Record([("cs_n", 1), ("clk", 1), ("dq", 4)]) + self.submodules.slave = SpiFlash(self.pads) + self.submodules.tap = wishbone.Tap(self.slave.bus) + self.submodules.intercon = wishbone.InterconnectPointToPoint( + self.master.bus, self.slave.bus) + self.cycle = 0 + + def gen_reads(self): + for a in range(10): + t = TRead(a) + yield t + print("read {} in {} cycles(s)".format(t.data, t.latency)) + + def do_simulation(self, selfp): + if selfp.pads.cs_n: + self.cycle = 0 + else: + self.cycle += 1 + if not selfp.slave.dq.oe: + selfp.slave.dq.i = self.cycle & 0xf + do_simulation.passive = True + +if __name__ == "__main__": + from migen.sim.generic import run_simulation + from migen.fhdl import verilog + + pads = Record([("cs_n", 1), ("clk", 1), ("dq", 4)]) + s = SpiFlash(pads) + print(verilog.convert(s, ios={pads.clk, pads.cs_n, pads.dq, s.bus.adr, + s.bus.dat_r, s.bus.cyc, s.bus.ack, s.bus.stb})) + + run_simulation(SpiFlashTB(), vcd_name="spiflash.vcd") diff --git a/misoclib/mem/flash/spiflash/__init__.py b/misoclib/mem/flash/spiflash/__init__.py deleted file mode 100644 index f842bfdf..00000000 --- a/misoclib/mem/flash/spiflash/__init__.py +++ /dev/null @@ -1,181 +0,0 @@ -from migen.fhdl.std import * -from migen.bus.transactions import * -from migen.bus import wishbone -from migen.genlib.misc import timeline -from migen.genlib.record import Record -from migen.bank.description import AutoCSR, CSRStorage, CSRStatus - -_FAST_READ = 0x0b -_DIOFR = 0xbb -_QIOFR = 0xeb - - -def _format_cmd(cmd, spi_width): - """ - `cmd` is the read instruction. Since everything is transmitted on all - dq lines (cmd, adr and data), extend/interleave cmd to full pads.dq - width even if dq1-dq3 are don't care during the command phase: - For example, for N25Q128, 0xeb is the quad i/o fast read, and - extended to 4 bits (dq1,dq2,dq3 high) is: 0xfffefeff - """ - c = 2**(8*spi_width)-1 - for b in range(8): - if not (cmd>>b)%2: - c &= ~(1<<(b*spi_width)) - return c - - -class SpiFlash(Module, AutoCSR): - def __init__(self, pads, dummy=15, div=2, with_bitbang=True): - """ - Simple SPI flash, e.g. N25Q128 on the LX9 Microboard. - - Supports multi-bit pseudo-parallel reads (aka Dual or Quad I/O Fast - Read). Only supports mode0 (cpol=0, cpha=0). - Optionally supports software bitbanging (for write, erase, or other commands). - """ - self.bus = bus = wishbone.Interface() - spi_width = flen(pads.dq) - if with_bitbang: - self.bitbang = CSRStorage(4) - self.miso = CSRStatus() - self.bitbang_en = CSRStorage() - - ### - - cs_n = Signal(reset=1) - clk = Signal() - dq_oe = Signal() - wbone_width = flen(bus.dat_r) - - - read_cmd_params = { - 4: (_format_cmd(_QIOFR, 4), 4*8), - 2: (_format_cmd(_DIOFR, 2), 2*8), - 1: (_format_cmd(_FAST_READ, 1), 1*8) - } - read_cmd, cmd_width = read_cmd_params[spi_width] - addr_width = 24 - - pads.cs_n.reset = 1 - - dq = TSTriple(spi_width) - self.specials.dq = dq.get_tristate(pads.dq) - - sr = Signal(max(cmd_width, addr_width, wbone_width)) - dqs = Replicate(1, spi_width-1) - - self.comb += bus.dat_r.eq(sr) - - hw_read_logic = [ - pads.clk.eq(clk), - pads.cs_n.eq(cs_n), - dq.o.eq(sr[-spi_width:]), - dq.oe.eq(dq_oe) - ] - - if with_bitbang: - bitbang_logic = [ - pads.clk.eq(self.bitbang.storage[1]), - pads.cs_n.eq(self.bitbang.storage[2]), - dq.o.eq(Cat(self.bitbang.storage[0], dqs)), - If(self.bitbang.storage[3], - dq.oe.eq(0) - ).Else( - dq.oe.eq(1) - ), - If(self.bitbang.storage[1], - self.miso.status.eq(dq.i[-1]) - ) - ] - - self.comb += \ - If(self.bitbang_en.storage, - bitbang_logic - ).Else( - hw_read_logic - ) - else: - self.comb += hw_read_logic - - if div < 2: - raise ValueError("Unsupported value \'{}\' for div parameter for SpiFlash core".format(div)) - else: - i = Signal(max=div) - dqi = Signal(spi_width) - self.sync += [ - If(i == div//2 - 1, - clk.eq(1), - dqi.eq(dq.i), - ), - If(i == div - 1, - i.eq(0), - clk.eq(0), - sr.eq(Cat(dqi, sr[:-spi_width])) - ).Else( - i.eq(i + 1), - ), - ] - - # spi is byte-addressed, prefix by zeros - z = Replicate(0, log2_int(wbone_width//8)) - - seq = [ - (cmd_width//spi_width*div, - [dq_oe.eq(1), cs_n.eq(0), sr[-cmd_width:].eq(read_cmd)]), - (addr_width//spi_width*div, - [sr[-addr_width:].eq(Cat(z, bus.adr))]), - ((dummy + wbone_width//spi_width)*div, - [dq_oe.eq(0)]), - (1, - [bus.ack.eq(1), cs_n.eq(1)]), - (div, # tSHSL! - [bus.ack.eq(0)]), - (0, - []), - ] - - # accumulate timeline deltas - t, tseq = 0, [] - for dt, a in seq: - tseq.append((t, a)) - t += dt - - self.sync += timeline(bus.cyc & bus.stb & (i == div - 1), tseq) - - -class SpiFlashTB(Module): - def __init__(self): - self.submodules.master = wishbone.Initiator(self.gen_reads()) - self.pads = Record([("cs_n", 1), ("clk", 1), ("dq", 4)]) - self.submodules.slave = SpiFlash(self.pads) - self.submodules.tap = wishbone.Tap(self.slave.bus) - self.submodules.intercon = wishbone.InterconnectPointToPoint( - self.master.bus, self.slave.bus) - self.cycle = 0 - - def gen_reads(self): - for a in range(10): - t = TRead(a) - yield t - print("read {} in {} cycles(s)".format(t.data, t.latency)) - - def do_simulation(self, selfp): - if selfp.pads.cs_n: - self.cycle = 0 - else: - self.cycle += 1 - if not selfp.slave.dq.oe: - selfp.slave.dq.i = self.cycle & 0xf - do_simulation.passive = True - -if __name__ == "__main__": - from migen.sim.generic import run_simulation - from migen.fhdl import verilog - - pads = Record([("cs_n", 1), ("clk", 1), ("dq", 4)]) - s = SpiFlash(pads) - print(verilog.convert(s, ios={pads.clk, pads.cs_n, pads.dq, s.bus.adr, - s.bus.dat_r, s.bus.cyc, s.bus.ack, s.bus.stb})) - - run_simulation(SpiFlashTB(), vcd_name="spiflash.vcd") diff --git a/misoclib/others/mxcrg.py b/misoclib/others/mxcrg.py new file mode 100644 index 00000000..673530c6 --- /dev/null +++ b/misoclib/others/mxcrg.py @@ -0,0 +1,41 @@ +from fractions import Fraction + +from migen.fhdl.std import * + + +class MXCRG(Module): + def __init__(self, pads, outfreq1x): + self.clock_domains.cd_sys = ClockDomain() + self.clock_domains.cd_sdram_half = ClockDomain() + self.clock_domains.cd_sdram_full_wr = ClockDomain() + self.clock_domains.cd_sdram_full_rd = ClockDomain() + self.clock_domains.cd_base50 = ClockDomain(reset_less=True) + + self.clk4x_wr_strb = Signal() + self.clk4x_rd_strb = Signal() + + ### + + infreq = 50*1000000 + ratio = Fraction(outfreq1x)/Fraction(infreq) + in_period = float(Fraction(1000000000)/Fraction(infreq)) + + self.specials += Instance("mxcrg", + Instance.Parameter("in_period", in_period), + Instance.Parameter("f_mult", ratio.numerator), + Instance.Parameter("f_div", ratio.denominator), + Instance.Input("clk50_pad", pads.clk50), + Instance.Input("trigger_reset", pads.trigger_reset), + + Instance.Output("sys_clk", self.cd_sys.clk), + Instance.Output("sys_rst", self.cd_sys.rst), + Instance.Output("clk2x_270", self.cd_sdram_half.clk), + Instance.Output("clk4x_wr", self.cd_sdram_full_wr.clk), + Instance.Output("clk4x_rd", self.cd_sdram_full_rd.clk), + Instance.Output("base50_clk", self.cd_base50.clk), + + Instance.Output("clk4x_wr_strb", self.clk4x_wr_strb), + Instance.Output("clk4x_rd_strb", self.clk4x_rd_strb), + Instance.Output("norflash_rst_n", pads.norflash_rst_n), + Instance.Output("ddr_clk_pad_p", pads.ddr_clk_p), + Instance.Output("ddr_clk_pad_n", pads.ddr_clk_n)) diff --git a/misoclib/others/mxcrg.v b/misoclib/others/mxcrg.v new file mode 100644 index 00000000..140c8483 --- /dev/null +++ b/misoclib/others/mxcrg.v @@ -0,0 +1,247 @@ +module mxcrg #( + parameter in_period = 0.0, + parameter f_mult = 0, + parameter f_div = 0, + parameter clk2x_period = (in_period*f_div)/(2.0*f_mult) +) ( + input clk50_pad, + input trigger_reset, + + output sys_clk, + output reg sys_rst, + + /* Reset NOR flash */ + output norflash_rst_n, + + /* DDR PHY clocks */ + output clk2x_270, + output clk4x_wr, + output clk4x_wr_strb, + output clk4x_rd, + output clk4x_rd_strb, + + /* DDR off-chip clocking */ + output ddr_clk_pad_p, + output ddr_clk_pad_n, + + /* Base clock, buffered */ + output base50_clk +); + +/* + * Reset + */ + +reg [19:0] rst_debounce; +always @(posedge sys_clk) begin + if(trigger_reset) + rst_debounce <= 20'hFFFFF; + else if(rst_debounce != 20'd0) + rst_debounce <= rst_debounce - 20'd1; + sys_rst <= rst_debounce != 20'd0; +end + +initial rst_debounce <= 20'hFFFFF; + +/* + * We must release the Flash reset before the system reset + * because the Flash needs some time to come out of reset + * and the CPU begins fetching instructions from it + * as soon as the system reset is released. + * From datasheet, minimum reset pulse width is 100ns + * and reset-to-read time is 150ns. + */ + +reg [7:0] flash_rstcounter; + +always @(posedge sys_clk) begin + if(trigger_reset) + flash_rstcounter <= 8'd0; + else if(~flash_rstcounter[7]) + flash_rstcounter <= flash_rstcounter + 8'd1; +end + +initial flash_rstcounter <= 8'd0; + +assign norflash_rst_n = flash_rstcounter[7]; + +/* + * Clock management. Inspired by the NWL reference design. + */ + +wire sdr_clk50; +wire clkdiv; + +IBUF #( + .IOSTANDARD("DEFAULT") +) clk2_iob ( + .I(clk50_pad), + .O(sdr_clk50) +); + +BUFIO2 #( + .DIVIDE(1), + .DIVIDE_BYPASS("FALSE"), + .I_INVERT("FALSE") +) bufio2_inst2 ( + .I(sdr_clk50), + .IOCLK(), + .DIVCLK(clkdiv), + .SERDESSTROBE() +); + +wire pll_lckd; +wire buf_pll_fb_out; +wire pllout0; +wire pllout1; +wire pllout2; +wire pllout3; +wire pllout4; +wire pllout5; + +PLL_ADV #( + .BANDWIDTH("OPTIMIZED"), + .CLKFBOUT_MULT(4*f_mult), + .CLKFBOUT_PHASE(0.0), + .CLKIN1_PERIOD(in_period), + .CLKIN2_PERIOD(in_period), + + .CLKOUT0_DIVIDE(f_div), + .CLKOUT0_DUTY_CYCLE(0.5), + .CLKOUT0_PHASE(0.0), + + .CLKOUT1_DIVIDE(f_div), + .CLKOUT1_DUTY_CYCLE(0.5), + .CLKOUT1_PHASE(0.0), + + .CLKOUT2_DIVIDE(2*f_div), + .CLKOUT2_DUTY_CYCLE(0.5), + .CLKOUT2_PHASE(270.0), + + .CLKOUT3_DIVIDE(4*f_div), + .CLKOUT3_DUTY_CYCLE(0.5), + .CLKOUT3_PHASE(0.0), + + .CLKOUT4_DIVIDE(4*f_mult), + .CLKOUT4_DUTY_CYCLE(0.5), + .CLKOUT4_PHASE(0.0), + + .CLKOUT5_DIVIDE(2*f_div), + .CLKOUT5_DUTY_CYCLE(0.5), + .CLKOUT5_PHASE(250.0), + + .COMPENSATION("INTERNAL"), + .DIVCLK_DIVIDE(1), + .REF_JITTER(0.100), + .CLK_FEEDBACK("CLKFBOUT"), + .SIM_DEVICE("SPARTAN6") +) pll ( + .CLKFBDCM(), + .CLKFBOUT(buf_pll_fb_out), + .CLKOUT0(pllout0), /* < x4 clock for writes */ + .CLKOUT1(pllout1), /* < x4 clock for reads */ + .CLKOUT2(pllout2), /* < x2 270 clock for DQS, memory address and control signals */ + .CLKOUT3(pllout3), /* < x1 clock for system and memory controller */ + .CLKOUT4(pllout4), /* < buffered clk50 */ + .CLKOUT5(pllout5), /* < x2 clock to off-chip DDR */ + .CLKOUTDCM0(), + .CLKOUTDCM1(), + .CLKOUTDCM2(), + .CLKOUTDCM3(), + .CLKOUTDCM4(), + .CLKOUTDCM5(), + .DO(), + .DRDY(), + .LOCKED(pll_lckd), + .CLKFBIN(buf_pll_fb_out), + .CLKIN1(clkdiv), + .CLKIN2(1'b0), + .CLKINSEL(1'b1), + .DADDR(5'b00000), + .DCLK(1'b0), + .DEN(1'b0), + .DI(16'h0000), + .DWE(1'b0), + .RST(1'b0), + .REL(1'b0) +); + +BUFPLL #( + .DIVIDE(4) +) wr_bufpll ( + .PLLIN(pllout0), + .GCLK(sys_clk), + .LOCKED(pll_lckd), + .IOCLK(clk4x_wr), + .LOCK(), + .SERDESSTROBE(clk4x_wr_strb) +); + +BUFPLL #( + .DIVIDE(4) +) rd_bufpll ( + .PLLIN(pllout1), + .GCLK(sys_clk), + .LOCKED(pll_lckd), + .IOCLK(clk4x_rd), + .LOCK(), + .SERDESSTROBE(clk4x_rd_strb) +); + +BUFG bufg_x2_2( + .I(pllout2), + .O(clk2x_270) +); + +BUFG bufg_x1( + .I(pllout3), + .O(sys_clk) +); + +wire base50_clk; +BUFG bufg_50( + .I(pllout4), + .O(base50_clk) +); + +wire clk2x_off; +BUFG bufg_x2_offclk( + .I(pllout5), + .O(clk2x_off) +); + + +/* + * SDRAM clock + */ + +ODDR2 #( + .DDR_ALIGNMENT("NONE"), + .INIT(1'b0), + .SRTYPE("SYNC") +) sd_clk_forward_p ( + .Q(ddr_clk_pad_p), + .C0(clk2x_off), + .C1(~clk2x_off), + .CE(1'b1), + .D0(1'b1), + .D1(1'b0), + .R(1'b0), + .S(1'b0) +); +ODDR2 #( + .DDR_ALIGNMENT("NONE"), + .INIT(1'b0), + .SRTYPE("SYNC") +) sd_clk_forward_n ( + .Q(ddr_clk_pad_n), + .C0(clk2x_off), + .C1(~clk2x_off), + .CE(1'b1), + .D0(1'b0), + .D1(1'b1), + .R(1'b0), + .S(1'b0) +); + +endmodule diff --git a/misoclib/others/mxcrg/__init__.py b/misoclib/others/mxcrg/__init__.py deleted file mode 100644 index 673530c6..00000000 --- a/misoclib/others/mxcrg/__init__.py +++ /dev/null @@ -1,41 +0,0 @@ -from fractions import Fraction - -from migen.fhdl.std import * - - -class MXCRG(Module): - def __init__(self, pads, outfreq1x): - self.clock_domains.cd_sys = ClockDomain() - self.clock_domains.cd_sdram_half = ClockDomain() - self.clock_domains.cd_sdram_full_wr = ClockDomain() - self.clock_domains.cd_sdram_full_rd = ClockDomain() - self.clock_domains.cd_base50 = ClockDomain(reset_less=True) - - self.clk4x_wr_strb = Signal() - self.clk4x_rd_strb = Signal() - - ### - - infreq = 50*1000000 - ratio = Fraction(outfreq1x)/Fraction(infreq) - in_period = float(Fraction(1000000000)/Fraction(infreq)) - - self.specials += Instance("mxcrg", - Instance.Parameter("in_period", in_period), - Instance.Parameter("f_mult", ratio.numerator), - Instance.Parameter("f_div", ratio.denominator), - Instance.Input("clk50_pad", pads.clk50), - Instance.Input("trigger_reset", pads.trigger_reset), - - Instance.Output("sys_clk", self.cd_sys.clk), - Instance.Output("sys_rst", self.cd_sys.rst), - Instance.Output("clk2x_270", self.cd_sdram_half.clk), - Instance.Output("clk4x_wr", self.cd_sdram_full_wr.clk), - Instance.Output("clk4x_rd", self.cd_sdram_full_rd.clk), - Instance.Output("base50_clk", self.cd_base50.clk), - - Instance.Output("clk4x_wr_strb", self.clk4x_wr_strb), - Instance.Output("clk4x_rd_strb", self.clk4x_rd_strb), - Instance.Output("norflash_rst_n", pads.norflash_rst_n), - Instance.Output("ddr_clk_pad_p", pads.ddr_clk_p), - Instance.Output("ddr_clk_pad_n", pads.ddr_clk_n)) diff --git a/misoclib/others/mxcrg/mxcrg.v b/misoclib/others/mxcrg/mxcrg.v deleted file mode 100644 index 140c8483..00000000 --- a/misoclib/others/mxcrg/mxcrg.v +++ /dev/null @@ -1,247 +0,0 @@ -module mxcrg #( - parameter in_period = 0.0, - parameter f_mult = 0, - parameter f_div = 0, - parameter clk2x_period = (in_period*f_div)/(2.0*f_mult) -) ( - input clk50_pad, - input trigger_reset, - - output sys_clk, - output reg sys_rst, - - /* Reset NOR flash */ - output norflash_rst_n, - - /* DDR PHY clocks */ - output clk2x_270, - output clk4x_wr, - output clk4x_wr_strb, - output clk4x_rd, - output clk4x_rd_strb, - - /* DDR off-chip clocking */ - output ddr_clk_pad_p, - output ddr_clk_pad_n, - - /* Base clock, buffered */ - output base50_clk -); - -/* - * Reset - */ - -reg [19:0] rst_debounce; -always @(posedge sys_clk) begin - if(trigger_reset) - rst_debounce <= 20'hFFFFF; - else if(rst_debounce != 20'd0) - rst_debounce <= rst_debounce - 20'd1; - sys_rst <= rst_debounce != 20'd0; -end - -initial rst_debounce <= 20'hFFFFF; - -/* - * We must release the Flash reset before the system reset - * because the Flash needs some time to come out of reset - * and the CPU begins fetching instructions from it - * as soon as the system reset is released. - * From datasheet, minimum reset pulse width is 100ns - * and reset-to-read time is 150ns. - */ - -reg [7:0] flash_rstcounter; - -always @(posedge sys_clk) begin - if(trigger_reset) - flash_rstcounter <= 8'd0; - else if(~flash_rstcounter[7]) - flash_rstcounter <= flash_rstcounter + 8'd1; -end - -initial flash_rstcounter <= 8'd0; - -assign norflash_rst_n = flash_rstcounter[7]; - -/* - * Clock management. Inspired by the NWL reference design. - */ - -wire sdr_clk50; -wire clkdiv; - -IBUF #( - .IOSTANDARD("DEFAULT") -) clk2_iob ( - .I(clk50_pad), - .O(sdr_clk50) -); - -BUFIO2 #( - .DIVIDE(1), - .DIVIDE_BYPASS("FALSE"), - .I_INVERT("FALSE") -) bufio2_inst2 ( - .I(sdr_clk50), - .IOCLK(), - .DIVCLK(clkdiv), - .SERDESSTROBE() -); - -wire pll_lckd; -wire buf_pll_fb_out; -wire pllout0; -wire pllout1; -wire pllout2; -wire pllout3; -wire pllout4; -wire pllout5; - -PLL_ADV #( - .BANDWIDTH("OPTIMIZED"), - .CLKFBOUT_MULT(4*f_mult), - .CLKFBOUT_PHASE(0.0), - .CLKIN1_PERIOD(in_period), - .CLKIN2_PERIOD(in_period), - - .CLKOUT0_DIVIDE(f_div), - .CLKOUT0_DUTY_CYCLE(0.5), - .CLKOUT0_PHASE(0.0), - - .CLKOUT1_DIVIDE(f_div), - .CLKOUT1_DUTY_CYCLE(0.5), - .CLKOUT1_PHASE(0.0), - - .CLKOUT2_DIVIDE(2*f_div), - .CLKOUT2_DUTY_CYCLE(0.5), - .CLKOUT2_PHASE(270.0), - - .CLKOUT3_DIVIDE(4*f_div), - .CLKOUT3_DUTY_CYCLE(0.5), - .CLKOUT3_PHASE(0.0), - - .CLKOUT4_DIVIDE(4*f_mult), - .CLKOUT4_DUTY_CYCLE(0.5), - .CLKOUT4_PHASE(0.0), - - .CLKOUT5_DIVIDE(2*f_div), - .CLKOUT5_DUTY_CYCLE(0.5), - .CLKOUT5_PHASE(250.0), - - .COMPENSATION("INTERNAL"), - .DIVCLK_DIVIDE(1), - .REF_JITTER(0.100), - .CLK_FEEDBACK("CLKFBOUT"), - .SIM_DEVICE("SPARTAN6") -) pll ( - .CLKFBDCM(), - .CLKFBOUT(buf_pll_fb_out), - .CLKOUT0(pllout0), /* < x4 clock for writes */ - .CLKOUT1(pllout1), /* < x4 clock for reads */ - .CLKOUT2(pllout2), /* < x2 270 clock for DQS, memory address and control signals */ - .CLKOUT3(pllout3), /* < x1 clock for system and memory controller */ - .CLKOUT4(pllout4), /* < buffered clk50 */ - .CLKOUT5(pllout5), /* < x2 clock to off-chip DDR */ - .CLKOUTDCM0(), - .CLKOUTDCM1(), - .CLKOUTDCM2(), - .CLKOUTDCM3(), - .CLKOUTDCM4(), - .CLKOUTDCM5(), - .DO(), - .DRDY(), - .LOCKED(pll_lckd), - .CLKFBIN(buf_pll_fb_out), - .CLKIN1(clkdiv), - .CLKIN2(1'b0), - .CLKINSEL(1'b1), - .DADDR(5'b00000), - .DCLK(1'b0), - .DEN(1'b0), - .DI(16'h0000), - .DWE(1'b0), - .RST(1'b0), - .REL(1'b0) -); - -BUFPLL #( - .DIVIDE(4) -) wr_bufpll ( - .PLLIN(pllout0), - .GCLK(sys_clk), - .LOCKED(pll_lckd), - .IOCLK(clk4x_wr), - .LOCK(), - .SERDESSTROBE(clk4x_wr_strb) -); - -BUFPLL #( - .DIVIDE(4) -) rd_bufpll ( - .PLLIN(pllout1), - .GCLK(sys_clk), - .LOCKED(pll_lckd), - .IOCLK(clk4x_rd), - .LOCK(), - .SERDESSTROBE(clk4x_rd_strb) -); - -BUFG bufg_x2_2( - .I(pllout2), - .O(clk2x_270) -); - -BUFG bufg_x1( - .I(pllout3), - .O(sys_clk) -); - -wire base50_clk; -BUFG bufg_50( - .I(pllout4), - .O(base50_clk) -); - -wire clk2x_off; -BUFG bufg_x2_offclk( - .I(pllout5), - .O(clk2x_off) -); - - -/* - * SDRAM clock - */ - -ODDR2 #( - .DDR_ALIGNMENT("NONE"), - .INIT(1'b0), - .SRTYPE("SYNC") -) sd_clk_forward_p ( - .Q(ddr_clk_pad_p), - .C0(clk2x_off), - .C1(~clk2x_off), - .CE(1'b1), - .D0(1'b1), - .D1(1'b0), - .R(1'b0), - .S(1'b0) -); -ODDR2 #( - .DDR_ALIGNMENT("NONE"), - .INIT(1'b0), - .SRTYPE("SYNC") -) sd_clk_forward_n ( - .Q(ddr_clk_pad_n), - .C0(clk2x_off), - .C1(~clk2x_off), - .CE(1'b1), - .D0(1'b0), - .D1(1'b1), - .R(1'b0), - .S(1'b0) -); - -endmodule diff --git a/misoclib/soc/__init__.py b/misoclib/soc/__init__.py index 354339f3..3e3e1fff 100644 --- a/misoclib/soc/__init__.py +++ b/misoclib/soc/__init__.py @@ -7,7 +7,7 @@ from migen.bus import wishbone, csr, wishbone2csr from misoclib.com.uart.phy import UARTPHY from misoclib.com import uart from misoclib.cpu import lm32, mor1kx -from misoclib.cpu.peripherals import identifier, timer +from misoclib.cpu import identifier, timer def mem_decoder(address, start=26, end=29): diff --git a/targets/mlabs_video.py b/targets/mlabs_video.py index b05caae6..69ea8e7c 100644 --- a/targets/mlabs_video.py +++ b/targets/mlabs_video.py @@ -67,7 +67,7 @@ class BaseSoC(SDRAMSoC): INST "mxcrg/wr_bufpll" LOC = "BUFPLL_X0Y2"; INST "mxcrg/rd_bufpll" LOC = "BUFPLL_X0Y3"; """) - platform.add_source_dir(os.path.join("misoclib", "others", "mxcrg")) + platform.add_source_dir(os.path.join("misoclib", "others")) class MiniSoC(BaseSoC):