def set_horizontal_sync(self, m):
     "Calculate Horizontal sync."
     h = self.params.horizontal
     with m.If(watch_lfsr(m, self.x, h.sync_start - 1, name='hsync_start')):
         m.d.sync += self.horizontal_sync.eq(~self.horizontal_sync)
     with m.If(watch_lfsr(m, self.x, h.sync_end - 1, name='hsync_end')):
         m.d.sync += self.horizontal_sync.eq(~self.horizontal_sync)
 def set_vertical_sync(self, m):
     "Calculate Vertical sync"
     v = self.params.vertical
     with m.If(self.at_line_m1):
         with m.If(
                 watch_lfsr(m, self.y, v.sync_start - 1,
                            name='vsync_start')):
             m.d.sync += self.vertical_sync.eq(~self.vertical_sync)
         with m.If(watch_lfsr(m, self.y, v.sync_end - 1, name='vsync_end')):
             m.d.sync += self.vertical_sync.eq(~self.vertical_sync)
    def set_at_active_line_m2(self, m):
        "Calculate at_active_line_m2"
        h = self.params.horizontal

        def setval(val):
            m.d.sync += self.at_active_line_m2.eq(val)

        with m.If(watch_lfsr(m, self.x, h.total - 3)):
            with m.If(self.last_frame_line):
                setval(True)
            with m.If(~self.vertical_blanking):
                setval(True)
        with m.If(watch_lfsr(m, self.x, h.total - 2)):
            setval(False)
 def watch_coord(self, m, xp, yp, name):
     """Adds logic to module to generate a one cycle pulse on a synced signal when
        timing reaches x, y
     """
     # TODO: Speed up by calculating over several cycles
     # Calculate when to trigger
     tx, ty = self.params.add_clocks(xp, yp, -1)
     result = Signal(1, name=name)
     x_at = Signal()
     y_at = Signal()
     m.d.sync += [
         x_at.eq(watch_lfsr(m, self.x, tx, name=f"{name}_x")),
         y_at.eq(watch_lfsr(m, self.y, ty, name=f"{name}_y")),
     ]
     m.d.comb += result.eq(x_at & y_at)
     return result
 def elaborate(self, plat):
     lfsr = Lfsr.num_steps(1100)
     led = plat.request('led_r')
     m = Module()
     m.d.sync += led.eq(lfsr.value[0])
     m.d.comb += lfsr.restart.eq(watch_lfsr(m, lfsr, 999))
     m.submodules += [lfsr]
     return m
 def elaborate(self, plat):
     # 89.77 90.62 94.95 95.31 95.31 95.31 95.31 95.31 101.58 107.52
     lfsr = Lfsr.num_steps(1100, default_enabled=False)
     button = plat.request('button')
     led = plat.request('led_r')
     m = Module()
     m.d.sync += led.eq(lfsr.value[0])
     m.d.comb += lfsr.restart.eq(watch_lfsr(m, lfsr, 999))
     m.d.comb += lfsr.enable.eq(button)
     m.submodules += [lfsr]
     return m
    def set_starts(self, m, last_y):
        """Calculate line start and frame start signals. 

        Because at_line_m1 and at_frame_m1 are synchronous, they need to be calculated
        one clock before their values are used."""
        h = self.params.horizontal
        v = self.params.vertical

        last_x2 = Signal()
        m.d.comb += last_x2.eq(watch_lfsr(m, self.x, h.total - 2, name="h_m2"))
        m.d.sync += self.at_line_m1.eq(
            last_x2)  # high on next clock, which is last for line

        with m.If(self.at_line_m1):
            m.d.sync += self.last_frame_line.eq(
                watch_lfsr(m, self.y, v.total - 2, name="v_m2"))
        at_frame_m3 = Signal()
        m.d.comb += at_frame_m3.eq(
            self.watch_coord(m, *self.params.add_clocks(0, 0, -3),
                             name="f_m3"))
        m.d.sync += self.at_frame_m2.eq(at_frame_m3)
        m.d.sync += self.at_frame_m1.eq(self.at_frame_m2)
 def elaborate(self, plat):
     lfsr1 = Lfsr.num_steps(1200)
     lfsr2 = Lfsr.num_steps(1000, default_enabled=False)
     led1 = plat.request('led_r')
     led2 = plat.request('led_g')
     m = Module()
     # Use both LFSRs
     m.d.sync += [
         led1.eq(lfsr1.value[0]),
         led2.eq(lfsr2.value[0]),
     ]
     # step lfsr2 when lfsr 1 is about to restart
     m.d.sync += [lfsr2.enable.eq(watch_lfsr(m, lfsr1, 1199))]
     m.submodules += [lfsr1, lfsr2]
     return m
Exemple #9
0
 def elaborate_read(self, m):
     """Make logic to build read_addr signal."""
     m.submodules.r_lfsr = r_lfsr = rename_sync(self.read_domain,
                                                self.make_lfsr())
     on_last = watch_lfsr(m,
                          r_lfsr,
                          self.num_words - 1,
                          domain=self.read_domain,
                          name='last')
     m.d.comb += [
         # Address is whatever LFSR says. Last is on last word
         self.read.addr.eq(r_lfsr.value),
         self.read.last.eq(on_last),
         # restart LFSR on toggle, step LFSR on r_next
         r_lfsr.restart.eq(self.read.toggle),
         r_lfsr.enable.eq(self.read.next),
     ]
    def set_active(self, m):
        "Calculate active signal"
        # NOTE: Previously, was using < operation, which is effetively a subtraction and
        # subtractions are slow. Changed to use == with stateful operation - is going better

        h = self.params.horizontal
        v = self.params.vertical
        at_active_end = watch_lfsr(m, self.x, h.active - 1, name='hactive_end')

        with m.If(self.at_frame_m1):
            # next pixel is top of screen
            m.d.sync += self.active.eq(True)
        with m.Elif(self.at_line_m1 & ~self.vertical_blanking):
            # For all except last line, set active when next line is about to begin
            m.d.sync += self.active.eq(True)
        with m.Elif(at_active_end):
            # Turn off at end of horizontal display area
            m.d.sync += self.active.eq(False)
    def elaborate(self, platform):
        m = Module()
        m.submodules += [self.x, self.y]

        # Step y at end of every line
        m.d.comb += self.y.enable.eq(self.at_line_m1)

        last_y = Signal()
        m.d.comb += last_y.eq(
            watch_lfsr(m, self.y, self.params.vertical.value_at_last))

        self.set_starts(m, last_y)
        self.set_at_active_line_m1(m)
        self.set_at_active_line_m2(m)
        self.set_horizontal_sync(m)
        self.set_vertical_sync(m)
        self.set_vertical_blanking(m)
        self.set_active(m)
        return m
    def elaborate(self, platform):
        m = Module()
        self.connect_line_shifter(m)

        # Tag is the current db read item after line is shifted out
        tag = self.db.data if self.debug else self.db.data[0]
        first_line = Signal()
        m.d.comb += first_line.eq(watch_lfsr(m, self.vt.y, 0))

        # Runs once per line, after line shifter done
        # DB should be pointing to first word (aka "tag")
        with m.If(self.line_shifter.done):
            # Always toggle after showing first line. Also toggle if tag is zero.
            # By happy coincidence, at reset will also toggle for first line
            # because first item from DB reads as zero
            with m.If((tag == 0) | first_line):
                m.d.comb += self.db.toggle.eq(1)
            with m.Else():
                # If didn't toggle, loop back to start
                m.d.comb += self.db.next.eq(1)

        return m