Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 2 commits
  • 7 files changed
  • 0 commit comments
  • 1 contributor
View
6 examples/basic/psync.py
@@ -4,10 +4,10 @@
from migen.genlib.cdc import *
class XilinxMultiRegImpl(MultiRegImpl):
- def get_fragment(self):
- disable_srl = set(SynthesisDirective("attribute shreg_extract of {r} is no", r=r)
+ def __init__(self, *args, **kwargs):
+ MultiRegImpl.__init__(self, *args, **kwargs)
+ self.specials += set(SynthesisDirective("attribute shreg_extract of {r} is no", r=r)
for r in self.regs)
- return MultiRegImpl.get_fragment(self) + Fragment(specials=disable_srl)
class XilinxMultiReg:
@staticmethod
View
16 examples/sim/basic1.py
@@ -6,9 +6,13 @@
# Our simple counter, which increments at every cycle
# and prints its current value in simulation.
-class Counter:
+class Counter(Module):
def __init__(self):
self.count = Signal(4)
+
+ # At each cycle, increase the value of the count signal.
+ # We do it with convertible/synthesizable FHDL code.
+ self.sync += self.count.eq(self.count + 1)
# This function will be called at every cycle.
def do_simulation(self, s):
@@ -19,19 +23,11 @@ def do_simulation(self, s):
# Count: 2
# ...
print("Count: " + str(s.rd(self.count)))
-
- def get_fragment(self):
- # At each cycle, increase the value of the count signal.
- # We do it with convertible/synthesizable FHDL code.
- sync = [self.count.eq(self.count + 1)]
- # List our simulation function in the fragment.
- sim = [self.do_simulation]
- return Fragment(sync=sync, sim=sim)
def main():
dut = Counter()
# We do not specify a top-level nor runner object, and use the defaults.
- sim = Simulator(dut.get_fragment())
+ sim = Simulator(dut)
# Since we do not use sim.interrupt, limit the simulation
# to some number of cycles.
sim.run(20)
View
11 examples/sim/basic2.py
@@ -7,11 +7,13 @@
# A slightly improved counter.
# Has a clock enable (CE) signal, counts on more bits
# and resets with a negative number.
-class Counter:
+class Counter(Module):
def __init__(self):
self.ce = Signal()
# Demonstrate negative numbers and signals larger than 32 bits.
self.count = Signal((37, True), reset=-5)
+
+ self.sync += If(self.ce, self.count.eq(self.count + 1))
def do_simulation(self, s):
# Only assert CE every second cycle.
@@ -35,17 +37,12 @@ def do_simulation(self, s):
# Cycle: 3 Count: -4
# Cycle: 4 Count: -3
# ...
-
- def get_fragment(self):
- sync = [If(self.ce, self.count.eq(self.count + 1))]
- sim = [self.do_simulation]
- return Fragment(sync=sync, sim=sim)
def main():
dut = Counter()
# Instantiating the generic top-level ourselves lets us
# specify a VCD output file.
- sim = Simulator(dut.get_fragment(), TopLevel("my.vcd"))
+ sim = Simulator(dut, TopLevel("my.vcd"))
sim.run(20)
main()
View
9 examples/sim/memory.py
@@ -4,11 +4,11 @@
from migen.fhdl.std import *
from migen.sim.generic import Simulator
-class Mem:
+class Mem(Module):
def __init__(self):
# Initialize the beginning of the memory with integers
# from 0 to 19.
- self.mem = Memory(16, 2**12, init=list(range(20)))
+ self.specials.mem = Memory(16, 2**12, init=list(range(20)))
def do_simulation(self, s):
# Read the memory. Use the cycle counter as address.
@@ -22,13 +22,10 @@ def do_simulation(self, s):
# Demonstrate how to interrupt the simulator.
if value == 10:
s.interrupt = True
-
- def get_fragment(self):
- return Fragment(specials={self.mem}, sim=[self.do_simulation])
def main():
dut = Mem()
- sim = Simulator(dut.get_fragment())
+ sim = Simulator(dut)
# No need for a cycle limit here, we use sim.interrupt instead.
sim.run()
View
87 migen/genlib/buffers.py
@@ -1,87 +0,0 @@
-from migen.fhdl.std import *
-
-class ReorderSlot:
- def __init__(self, tag_width, data_width):
- self.wait_data = Signal()
- self.has_data = Signal()
- self.tag = Signal(tag_width)
- self.data = Signal(data_width)
-
-class ReorderBuffer:
- def __init__(self, tag_width, data_width, depth):
- self.depth = depth
-
- # issue
- self.can_issue = Signal()
- self.issue = Signal()
- self.tag_issue = Signal(tag_width)
-
- # call
- self.call = Signal()
- self.tag_call = Signal(tag_width)
- self.data_call = Signal(data_width)
-
- # readback
- self.can_read = Signal()
- self.read = Signal()
- self.data_read = Signal(data_width)
-
- self._empty_count = Signal(max=self.depth+1, reset=self.depth)
- self._produce = Signal(max=self.depth)
- self._consume = Signal(max=self.depth)
- self._slots = Array(ReorderSlot(tag_width, data_width)
- for n in range(self.depth))
-
- def get_fragment(self):
- # issue
- comb = [
- self.can_issue.eq(self._empty_count != 0)
- ]
- sync = [
- If(self.issue & self.can_issue,
- self._empty_count.eq(self._empty_count - 1),
- If(self._produce == self.depth - 1,
- self._produce.eq(0)
- ).Else(
- self._produce.eq(self._produce + 1)
- ),
- self._slots[self._produce].wait_data.eq(1),
- self._slots[self._produce].tag.eq(self.tag_issue)
- )
- ]
-
- # call
- for n, slot in enumerate(self._slots):
- sync.append(
- If(self.call & slot.wait_data & (self.tag_call == slot.tag),
- slot.wait_data.eq(0),
- slot.has_data.eq(1),
- slot.data.eq(self.data_call)
- )
- )
-
- # readback
- comb += [
- self.can_read.eq(self._slots[self._consume].has_data),
- self.data_read.eq(self._slots[self._consume].data)
- ]
- sync += [
- If(self.read & self.can_read,
- self._empty_count.eq(self._empty_count + 1),
- If(self._consume == self.depth - 1,
- self._consume.eq(0)
- ).Else(
- self._consume.eq(self._consume + 1)
- ),
- self._slots[self._consume].has_data.eq(0)
- )
- ]
-
- # do not touch empty count when issuing and reading at the same time
- sync += [
- If(self.issue & self.can_issue & self.read & self.can_read,
- self._empty_count.eq(self._empty_count)
- )
- ]
-
- return Fragment(comb, sync)
View
27 migen/genlib/cdc.py
@@ -58,29 +58,24 @@ def list_clock_domains(self):
def lower(dr):
return MultiRegImpl(dr.i, dr.o, dr.odomain, dr.n)
-class PulseSynchronizer:
+class PulseSynchronizer(Module):
def __init__(self, idomain, odomain):
- self.idomain = idomain
- self.odomain = odomain
self.i = Signal()
self.o = Signal()
- def get_fragment(self):
+ ###
+
toggle_i = Signal()
toggle_o = Signal()
toggle_o_r = Signal()
- sync_i = [
- If(self.i, toggle_i.eq(~toggle_i))
- ]
- sync_o = [
- toggle_o_r.eq(toggle_o)
- ]
- comb = [
- self.o.eq(toggle_o ^ toggle_o_r)
- ]
- return Fragment(comb,
- {self.idomain: sync_i, self.odomain: sync_o},
- specials={MultiReg(toggle_i, toggle_o, self.odomain)})
+
+ sync_i = getattr(self.sync, idomain)
+ sync_o = getattr(self.sync, odomain)
+
+ sync_i += If(self.i, toggle_i.eq(~toggle_i))
+ self.specials += MultiReg(toggle_i, toggle_o, odomain)
+ sync_o += toggle_o_r.eq(toggle_o)
+ self.comb += self.o.eq(toggle_o ^ toggle_o_r)
class GrayCounter(Module):
def __init__(self, width):
View
76 migen/genlib/rob.py
@@ -0,0 +1,76 @@
+from migen.fhdl.std import *
+
+class ReorderSlot:
+ def __init__(self, tag_width, data_width):
+ self.wait_data = Signal()
+ self.has_data = Signal()
+ self.tag = Signal(tag_width)
+ self.data = Signal(data_width)
+
+class ReorderBuffer(Module):
+ def __init__(self, tag_width, data_width, depth):
+ # issue
+ self.can_issue = Signal()
+ self.issue = Signal()
+ self.tag_issue = Signal(tag_width)
+
+ # call
+ self.call = Signal()
+ self.tag_call = Signal(tag_width)
+ self.data_call = Signal(data_width)
+
+ # readback
+ self.can_read = Signal()
+ self.read = Signal()
+ self.data_read = Signal(data_width)
+
+ ###
+
+ empty_count = Signal(max=depth+1, reset=depth)
+ produce = Signal(max=depth)
+ consume = Signal(max=depth)
+ slots = Array(ReorderSlot(tag_width, data_width)
+ for n in range(depth))
+
+ # issue
+ self.comb += self.can_issue.eq(empty_count != 0)
+ self.sync += If(self.issue & self.can_issue,
+ empty_count.eq(empty_count - 1),
+ If(produce == depth - 1,
+ produce.eq(0)
+ ).Else(
+ produce.eq(produce + 1)
+ ),
+ slots[produce].wait_data.eq(1),
+ slots[produce].tag.eq(self.tag_issue)
+ )
+
+ # call
+ for n, slot in enumerate(slots):
+ self.sync += If(self.call & slot.wait_data & (self.tag_call == slot.tag),
+ slot.wait_data.eq(0),
+ slot.has_data.eq(1),
+ slot.data.eq(self.data_call)
+ )
+
+ # readback
+ self.comb += [
+ self.can_read.eq(slots[consume].has_data),
+ self.data_read.eq(slots[consume].data)
+ ]
+ self.sync += [
+ If(self.read & self.can_read,
+ empty_count.eq(empty_count + 1),
+ If(consume == depth - 1,
+ consume.eq(0)
+ ).Else(
+ consume.eq(consume + 1)
+ ),
+ slots[consume].has_data.eq(0)
+ )
+ ]
+
+ # do not touch empty count when issuing and reading at the same time
+ self.sync += If(self.issue & self.can_issue & self.read & self.can_read,
+ empty_count.eq(empty_count)
+ )

No commit comments for this range

Something went wrong with that request. Please try again.