Пример #1
0
    def run_general(self):
        last = self.time[1]
        m = self.module
        core: Core = self.uut
        comb = m.d.comb

        lhs = Signal(unsigned(core.xlen))
        rhs = Signal(unsigned(core.xlen))
        bgeu_res = Signal(name="bgeu_res")

        comb += lhs.eq(last.r[last.btype.rs1])
        comb += rhs.eq(last.r[last.btype.rs2])
        comb += bgeu_res.eq(lhs >= rhs)

        with m.If(bgeu_res):
            self.assert_jump_was_taken()
        with m.Else():
            self.assert_no_jump_taken()

        lhs_bz = Signal()  # bz = below-zero in signed  representation
        rhs_bz = Signal()
        comb += lhs_bz.eq(lhs[core.xlen - 1])
        comb += rhs_bz.eq(rhs[core.xlen - 1])

        with m.If(lhs_bz & (~rhs_bz)):
            self.assert_jump_was_taken()
        with m.Elif((~lhs_bz) & (rhs_bz)):
            self.assert_no_jump_taken()
Пример #2
0
    def run_general(self):
        last = self.time[1]
        m = self.module
        core: Core = self.uut
        comb = m.d.comb

        bltu_lhs = Signal(unsigned(core.xlen))
        bltu_rhs = Signal(unsigned(core.xlen))
        bltu_res = Signal(name="bltu_res")

        comb += bltu_lhs.eq(last.r[last.btype.rs1])
        comb += bltu_rhs.eq(last.r[last.btype.rs2])
        comb += bltu_res.eq(bltu_lhs < bltu_rhs)

        with m.If(bltu_res):
            self.assert_jump_was_taken()
        with m.Else():
            self.assert_no_jump_taken()

        bltu_lhs_bz = Signal()  # bz = below-zero in signed variant
        bltu_rhs_bz = Signal()
        comb += bltu_lhs_bz.eq(bltu_lhs[core.xlen - 1])
        comb += bltu_rhs_bz.eq(bltu_rhs[core.xlen - 1])

        with m.If(bltu_lhs_bz & (~bltu_rhs_bz)):
            self.assert_no_jump_taken()
        with m.Elif((~bltu_lhs_bz) & (bltu_rhs_bz)):
            self.assert_jump_was_taken()
Пример #3
0
    def comparison_impl(self, rv1, rv2):
        core : Core = self.core
        m = core.current_module
        comb = m.d.comb

        rv1_unsigned = Signal(unsigned(core.xlen))
        rv2_unsigned = Signal(unsigned(core.xlen))
        comb += rv1_unsigned.eq(rv1)
        comb += rv2_unsigned.eq(rv2)    
        return rv1_unsigned < rv2_unsigned
    def __init__(self, ParityCheckMatrix, codeword_width):

        #[PARAMETER] - codeword_width: Width of the output Codeword
        self.codeword_width = int(codeword_width)

        #[PARAMETER] - data_output_matrix_rows: Rows of the Generator Matrix
        self.data_output_matrix_rows = int(len(ParityCheckMatrix))

        #[CONSTANT] - parity_check_matrix: A parity check matrix constant
        self.parity_check_matrix = Array([
            Const(ParityCheckMatrix[_][0], unsigned(self.codeword_width))
            for _ in range(self.data_output_matrix_rows)
        ])

        #[INPUT] - start: The start signal to start the decoding process(codeword)
        self.start = Signal(1)

        #[INPUT] - data_input: The data to be encoded
        self.data_input = Signal(codeword_width)

        #[OUTPUT] - data_output: The result of each row parity check
        self.data_output = Signal(self.data_output_matrix_rows, reset=0)

        #[OUTPUT] - done: The done signal to indicate that the decoding process has stopped.
        self.done = Signal(1, reset=0)
Пример #5
0
    def __init__(self, GeneratorMatrix, codeword_width):

        #[PARAMETER] - codeword_width: Width of the output Codeword
        self.codeword_width = int(codeword_width)

        #[PARAMETER] - data_input_length: Width of the data input
        self.data_input_length = int(len(GeneratorMatrix))

        #[CONSTANT] - gen_matrix: A generator matrix constant
        self.gen_matrix = Array([
            Const(GeneratorMatrix[_][0], unsigned(self.codeword_width))
            for _ in range(self.data_input_length)
        ])

        #[INPUT] - start: The start signal to start the encoding process(codeword)
        self.start = Signal(1)

        #[INPUT] - data_input: The data to be encoded
        self.data_input = Signal(self.data_input_length)

        #[OUTPUT] - data_output: The encoded data (codeword)
        self.data_output = Signal(self.codeword_width, reset=0)

        #[OUTPUT] - done: The done signal to indicate that encoding has completed.
        self.done = Signal(1, reset=0)
Пример #6
0
 def __init__(self, name: str = None):
     super().__init__(
         Layout([
             ("address", unsigned(16)),
             ("data_in", unsigned(8)),
             ("data_out", unsigned(8)),
             ("rw", unsigned(1)),
             ("vma", unsigned(1)),
             ("ba", unsigned(1)),
             ("nmi", unsigned(1)),
             ("irq", unsigned(1)),
         ]),
         name=name,
     )
Пример #7
0
    def selftest():
        ps0 = PipeSpec(8)
        assert ps0.data_width == 8
        assert ps0.flags == 0
        assert type(ps0.dsol) is Shape
        assert ps0.dsol == unsigned(8)
        assert ps0.start_stop is False
        assert ps0.data_size is False
        assert ps0.as_int == 8
        pi0 = ps0.inlet()
        assert isinstance(pi0, PipeInlet)
        assert isinstance(pi0, Record)
        assert isinstance(pi0, Value)
        assert pi0.o_data.shape() == unsigned(8)
        c0 = pi0.flow_to(ps0.outlet())
        assert len(c0) == 3
        assert repr(c0[0]) == '(eq (sig i_data) (sig pi0__o_data))'
        assert repr(c0[1]) == '(eq (sig i_valid) (sig pi0__o_valid))'
        assert repr(c0[2]) == '(eq (sig pi0__i_ready) (sig o_ready))'

        ps1 = PipeSpec(signed(5), flags=DATA_SIZE)
        assert ps1.data_width == 5
        assert ps1.flags == DATA_SIZE
        assert type(ps1.dsol) is Shape
        assert ps1.dsol == signed(5)
        assert ps1.start_stop is False
        assert ps1.data_size is True
        assert ps1.as_int == 256 + 5
        pi1 = ps1.inlet()
        assert isinstance(pi1, PipeInlet)
        assert isinstance(pi1, Record)
        assert isinstance(pi1, Value)
        assert pi1.o_data.shape() == signed(5)
        c1 = ps1.outlet().flow_from(pi1)
        assert len(c1) == 4

        ps2 = PipeSpec((('a', signed(4)), ('b', unsigned(2))), flags=START_STOP)
        assert ps2.data_width == 6
        assert ps2.flags == START_STOP
        assert type(ps2.dsol) is Layout
        assert ps2.dsol == Layout((('a', signed(4)), ('b', unsigned(2))))
        assert ps2.start_stop is True
        assert ps2.data_size is False
        assert ps2.as_int == 512 + 6
        pi2 = ps2.inlet()
        assert isinstance(pi2, PipeInlet)
        assert isinstance(pi2, Record)
        assert isinstance(pi2, Value)
        assert pi2.o_data.shape() == unsigned(4 + 2)
        po2 = ps2.outlet()
        assert isinstance(po2, PipeOutlet)
        assert po2.i_data.shape() == unsigned(4 + 2)
        c2 = pi2.flow_to(po2)
        assert len(c2) == 5

        ps3 = PipeSpec.from_int(START_STOP | DATA_SIZE | 10)
        assert ps3.data_width == 10
        assert ps3.flags == START_STOP | DATA_SIZE
        assert type(ps3.dsol) is Shape
        assert ps3.dsol == unsigned(10)
        assert ps3.start_stop is True
        assert ps3.data_size is True
        assert ps3.as_int == 512 + 256 + 10
        pi3 = ps3.inlet(name='inlet_3')
        assert isinstance(pi3, PipeInlet)
        assert isinstance(pi3, Record)
        assert isinstance(pi3, Value)
        assert pi3.o_data.shape() == unsigned(10)
        inlet_3 = ps3.inlet()
        po3 = ps3.outlet(name='outlet_3')
        outlet_3 = ps3.outlet()
        assert repr(pi3) == repr(inlet_3)
        assert repr(po3) == repr(outlet_3)
        assert repr(pi3.fields) == repr(inlet_3.fields)
        assert repr(po3.fields) == repr(outlet_3.fields)
        c3 = pi3.flow_to(po3)
        c3a = outlet_3.flow_from(inlet_3)
        assert len(c3) == 6
        assert len(c3a) == 6
Пример #8
0
 def __init__(self):
     self.x = Signal(8)
     self.y = Signal(8)
     self.out = Signal(unsigned(8))
Пример #9
0
    def elaborate(self, platform):
        phase = Signal(self.phase_depth)
        note = Signal.like(self.note_in.i_data.note)
        mod = Signal.like(self.mod_in)
        pw = Signal.like(self.pw_in)
        octave = Signal(range(OCTAVES))
        step = Signal(range(STEPS))
        base_inc = Signal(self.inc_depth)
        step_incs = Array(
            [Signal.like(base_inc, reset=inc) for inc in self._base_incs])
        inc = Signal.like(phase)
        pulse_sample = Signal.like(self.pulse_out.o_data)
        saw_sample = Signal.like(self.saw_out.o_data)

        m = Module()
        with m.If(self.sync_in):
            m.d.sync += [
                phase.eq(0),
                # self.rdy_out.eq(False),
            ]

        m.d.comb += [
            self.note_in.o_ready.eq(True),
        ]
        with m.If(self.note_in.received()):
            m.d.sync += [
                note.eq(self.note_in.i_data.note),
                octave.eq(div12(self.note_in.i_data.note)),
            ]
        # Calculate pulse wave edges.  The pulse must rise and fall
        # exactly once per cycle.
        prev_msb = Signal()
        new_cycle = Signal()
        pulse_up = Signal()
        up_latch = Signal()
        pw8 = Cat(pw, Const(0, unsigned(1)))
        m.d.sync += [
            prev_msb.eq(phase[-1]),
        ]
        m.d.comb += [
            new_cycle.eq(~phase[-1] & prev_msb),
            # Widen pulse to one sample period minimum.
            pulse_up.eq(new_cycle | (up_latch & (phase[-8:] <= pw8))),
        ]
        m.d.sync += [
            up_latch.eq((new_cycle | up_latch) & pulse_up),
        ]

        with m.FSM():

            with m.State(FSM.START):
                m.d.sync += [
                    # note.eq(self.note_in),
                    mod.eq(self.mod_in),
                    pw.eq(self.pw_in),
                    # octave.eq(div12(self.note_in)),
                ]
                m.next = FSM.MODULUS

            with m.State(FSM.MODULUS):
                m.d.sync += [
                    step.eq(note - mul12(octave)),
                ]
                m.next = FSM.LOOKUP

            with m.State(FSM.LOOKUP):
                m.d.sync += [
                    base_inc.eq(step_incs[step]),
                ]
                # m.next = FSM.MODULATE
                m.next = FSM.SHIFT

            # with m.State(FSM.MODULATE):
            #     ...
            #     m.next = FSM.SHIFT

            with m.State(FSM.SHIFT):
                m.d.sync += [
                    inc.eq((base_inc << octave)[-self.shift:]),
                ]
                m.next = FSM.ADD

            with m.State(FSM.ADD):
                m.d.sync += [
                    phase.eq(phase + inc),
                ]
                m.next = FSM.SAMPLE

            with m.State(FSM.SAMPLE):
                samp_depth = self.saw_out.o_data.shape()[0]
                samp_max = 2**(samp_depth - 1) - 1
                m.d.sync += [
                    pulse_sample.eq(Mux(pulse_up, samp_max, -samp_max)),
                    saw_sample.eq(samp_max - phase[-samp_depth:]),
                ]
                m.next = FSM.EMIT

            with m.State(FSM.EMIT):
                with m.If(self.saw_out.i_ready & self.pulse_out.i_ready):
                    m.d.sync += [
                        self.pulse_out.o_valid.eq(True),
                        self.pulse_out.o_data.eq(pulse_sample),
                        self.saw_out.o_valid.eq(True),
                        self.saw_out.o_data.eq(saw_sample),
                    ]
                    m.next = FSM.START

        with m.If(self.pulse_out.sent()):
            m.d.sync += [
                self.pulse_out.o_valid.eq(False),
            ]
        with m.If(self.saw_out.sent()):
            m.d.sync += [
                self.saw_out.o_valid.eq(False),
            ]
        return m
    def elaborate(self, platform):
        #Instantiate the Module
        m = Module()

        #[ARRAY[SIGNAL]] - stage_1_working_matrix - An array of signals which represents the parity matrix used to validate the input codeword
        stage_1_working_matrix = Array([
            Signal(unsigned(self.codeword_width), reset=0)
            for _ in range(self.data_output_matrix_rows)
        ])

        #[ARRAY[SIGNAL]] - stage_2_adder_buffer - An array of signals which are used to calculate whether there are an even number of 1s in each parity check row
        stage_2_adder_buffer = Array([
            Signal(unsigned(self.codeword_width),
                   reset=0,
                   name="stage_2_adder_buffer")
            for _ in range(self.data_output_matrix_rows)
        ])

        #[SIGNAL] - stage_2_counter - Counts the worst case scenario for the even 1s calculation
        stage_2_counter = Signal(self.codeword_width)

        #[SIGNAL] - pipeline_stage - Signal to indicate whether we are in pipeline stage 0 or 1
        pipeline_stage = Signal(1)
        #[SIGNAL] - running - Signal to indicate that we are currently running
        running = Signal(1, reset=0)

        #if start bit is asserted, reset the system
        with m.If(self.start):
            for i in range(0, self.data_output_matrix_rows):
                m.d.sync += [
                    running.eq(1),
                    stage_1_working_matrix[i].eq(0),
                    stage_2_adder_buffer[i].eq(0),
                    stage_2_counter.eq(0),
                    self.done.eq(0),
                    self.data_output.eq(0b000),
                    pipeline_stage.eq(0),
                ]
        #First Pipeline Stage (0)
        #Data_input ANDed with each row of the parity check matrix
        with m.If(running & (pipeline_stage == 0)):
            for i in range(0, self.data_output_matrix_rows):
                m.d.sync += [
                    stage_1_working_matrix[i].eq(self.data_input
                                                 & self.parity_check_matrix[i])
                ]
            m.d.sync += [pipeline_stage.eq(1)]

        #Second Pipeline Stage (1)
        #Accumulate the ANDed data to calculate if there are an even number of 1s.
        with m.If(running & (pipeline_stage == 1)):
            m.d.sync += [stage_2_counter.eq(stage_2_counter + 1)]
            for i in range(0, self.data_output_matrix_rows):
                for n in range(1, self.codeword_width):
                    if (n == 1):
                        m.d.sync += [
                            stage_2_adder_buffer[i]
                            [n].eq(stage_1_working_matrix[i][n]
                                   ^ stage_1_working_matrix[i][n - 1])
                        ]
                    else:
                        m.d.sync += [
                            stage_2_adder_buffer[i]
                            [n].eq(stage_2_adder_buffer[i][n - 1]
                                   ^ stage_1_working_matrix[i][n])
                        ]
        #Output the result of each parity check row comparison (1=Fail, 0=Pass)
            with m.If(stage_2_counter == (self.codeword_width)):
                for i in range(0, self.data_output_matrix_rows):
                    m.d.sync += [
                        self.data_output[(self.data_output_matrix_rows - 1) -
                                         i].eq(stage_2_adder_buffer[i][
                                             self.codeword_width - 1]),
                        running.eq(0),
                        self.done.eq(1)
                    ]

        return m
Пример #11
0
    def elaborate(self, platform):
        #Instantiate the Module
        m = Module()

        #[ARRAY[SIGNAL]] - working_matrix - An array of signals which represents the matrix used to calculate the output codeword.
        working_matrix = Array([
            Signal(unsigned(self.codeword_width), reset=0)
            for _ in range(self.data_input_length)
        ])

        #[ARRAY[SIGNAL]] - adder_buffer - An array of signals which is used to accumulate the columns of the working matrix to calculate the codeword
        adder_buffer = Array([
            Signal(unsigned(self.data_input_length), reset=0)
            for _ in range(self.codeword_width)
        ])

        #[SIGNAL] - cnt - A signal to count the steps completed in the encoding process
        cnt = Signal(self.data_input_length)

        #[SIGNAL] - running - A signal which is used to indicate the pipeline is running.
        running = Signal(1, reset=0)

        #[SIGNAL] - accumulation_completed - A signal which is used to indicate when the accumulation process has completed.
        accumulation_completed = Signal(1)

        #[SIGNAL] - data_input_copy - Internal copy of the data_input
        data_input_copy = Signal(self.data_input_length)

        #The accumulation process completes in fixed time complexity in (n-1) clock cycles, where n is the length of the data input
        m.d.comb += accumulation_completed.eq(cnt == self.data_input_length -
                                              1)

        #If 'start' is asserted, reset the adder_buffer, cnt, done and output variables.
        with m.If(self.start):
            for i in range(0, self.codeword_width):
                m.d.sync += [adder_buffer[i].eq(0)]
            m.d.sync += [
                cnt.eq(0),
                self.done.eq(0),
                self.data_output.eq(0),
                data_input_copy.eq(self.data_input),
                running.eq(1)
            ]

        #If 'accumulation_completed' is not satisfied, increment cnt
        with m.Elif(~accumulation_completed & running):
            m.d.sync += [cnt.eq(cnt + 1)]

            #Complete the first stage of the accumulation - AND the input data with the genmatrix
            #Since this is in the combinatorial domain, there is 'no penalty' as the size of the generator matrix and data input increases
            for i in range(0, self.codeword_width):
                for n in range(0, self.data_input_length):
                    m.d.comb += [
                        working_matrix[n][i].
                        eq(self.gen_matrix[n][i]
                           & data_input_copy[(self.data_input_length - n) - 1])
                    ]

        #Accumulate the columns of the matrix, with the Gallagher Modulo 2 rules
        #https://ieeexplore.ieee.org/document/1057683
            for i in range(0, self.codeword_width):
                for n in range(1, self.data_input_length):
                    if (n == 1):
                        m.d.sync += [
                            adder_buffer[i][n].eq(working_matrix[n][i]
                                                  ^ working_matrix[n - 1][i])
                        ]
                    else:
                        m.d.sync += [
                            adder_buffer[i][n].eq(adder_buffer[i][n - 1]
                                                  ^ working_matrix[n][i])
                        ]

        #Present the result on the output register and set the 'done' flag.
        with m.Elif(accumulation_completed & running):
            for i in range(0, self.codeword_width):
                m.d.sync += [
                    self.data_output[i].eq(
                        adder_buffer[i][self.data_input_length - 1]),
                    self.done.eq(1),
                    running.eq(0)
                ]

        return m
Пример #12
0
#!/usr/bin/env nmigen

from nmigen import Const, Elaboratable, Module, Signal, unsigned

from nmigen_lib.pipe import PipeSpec
from nmigen_lib.util.main import Main
from nmigen_lib.util import delay

from synth.midi import note_msg_spec


voice_note_spec = PipeSpec((
    ('note', unsigned(7)),
))

voice_gate_spec = PipeSpec((
    ('gate', unsigned(1)),
    ('velocity', unsigned(7)),
))


class MonoPriority(Elaboratable):

    """Choose highest priority notes for monophonic synth.

       Channel = None means merge all MIDI channels.
       use_velocity: if false, output velocity is constant at 64.
    """

    def __init__(self, channel=None, use_velocity=False):
        self.channel = channel
Пример #13
0
    def elaborate(self, platform):
        #Instantiate the Module
        m = Module()

        #Instantiate a decoder/validator for each bit-flip combination of the input codeword
        for i in range(0, self.codeword_width + 1):
            m.submodules["decoder" + str(i)] = LDPC_Decoder_Validator(
                self.ParityCheckMatrixPythonArray, self.codeword_width)

        #codeword_list - An array containing the input codeword and copies of the input codeword, each with a different bit flipped
        codeword_list = Array([
            Signal(unsigned(self.codeword_width), reset=0)
            for _ in range(self.codeword_width + 1)
        ])

        #decoder_output_list - An array containing the parity check status of each parity check row for an input codeword
        decoder_output_list = Array([
            Signal(unsigned(self.ParityCheckMatrixRows), reset=0)
            for _ in range(self.codeword_width + 1)
        ])

        #decoders_done - A signal which lets the top level know when the submodules have finished decoding/validating
        decoders_done = Signal(1)
        m.d.comb += decoders_done.eq(
            m.submodules["decoder" + str(self.codeword_width)].done)

        #counter - A timeout counter for catching when the decoder never finishes decoding
        counter = Signal(self.codeword_width)

        #pipeline_stage - A signal for keeping track of the pipeline stage
        pipeline_stage = Signal(3, reset=0)

        #pipeline_stage - A signal for starting the submodules
        start_submodules = Signal(1, reset=0)

        for i in range(0, self.codeword_width + 1):
            m.d.comb += m.submodules["decoder" +
                                     str(i)].start.eq(start_submodules)
            m.d.sync += m.submodules["decoder" + str(i)].data_input.eq(
                codeword_list[i])
            m.d.comb += decoder_output_list[i].eq(
                m.submodules["decoder" + str(i)].data_output)

        #Reset the relevant registers/wires and load the input codeword into a decoder input register
        with m.If(self.start):
            m.d.sync += [
                codeword_list[self.codeword_width].eq(self.data_input),
                self.data_output.eq(0),
                self.done.eq(0),
                self.success.eq(0),
                counter.eq(0),
                pipeline_stage.eq(1)
            ]
        #Load the input codeword into the codeword list
        with m.Elif(pipeline_stage == 1):
            for i in range(0, self.codeword_width):
                m.d.sync += [
                    codeword_list[i].eq(codeword_list[self.codeword_width]),
                    pipeline_stage.eq(pipeline_stage + 1)
                ]
        #Flip the relevant bit on the codewords in the codeword list
        with m.Elif(pipeline_stage == 2):
            for i in range(0, self.codeword_width):
                m.d.sync += [
                    codeword_list[i][i].eq(~codeword_list[i][i]),
                    pipeline_stage.eq(pipeline_stage + 1)
                ]
        #Start validating all the codeword variations (Set Start Bit to 1)
        with m.Elif(pipeline_stage == 3):
            for i in range(0, self.codeword_width):
                m.d.sync += [
                    start_submodules.eq(1),
                    pipeline_stage.eq(pipeline_stage + 1)
                ]
        #Start validating all the codeword variations (Set Start Bit to 0)
        with m.Elif(pipeline_stage == 4):
            for i in range(0, self.codeword_width):
                m.d.sync += [
                    start_submodules.eq(0),
                    pipeline_stage.eq(pipeline_stage + 1)
                ]
        #Start counting the timeout and validating if any of the submodules was successful in validating the codeword.
        #Finally, output success or failure along with output data and STOP.
        with m.Elif(pipeline_stage == 5 & (~self.done) & (~self.start)):
            for i in range(0, self.codeword_width + 1):
                m.d.sync += counter.eq(counter + 1)
            with m.If((decoders_done) & (counter > (self.codeword_width + 2))):
                m.d.sync += [self.done.eq(1), self.success.eq(0)]
            with m.Elif((decoders_done)):
                for i in range(0, self.codeword_width + 1):
                    with m.If(decoder_output_list[i] == 0b000):
                        m.d.sync += [
                            self.data_output.eq(codeword_list[
                                self.codeword_width][self.codeword_width -
                                                     self.data_output_width:]),
                            self.done.eq(1),
                            self.success.eq(1)
                        ]
        return m
Пример #14
0
#!/usr/bin/env nmigen

from collections import namedtuple

from nmigen import Elaboratable, Module, Signal, unsigned
from nmigen.asserts import Assert
from nmigen.back.pysim import Passive

from nmigen_lib.pipe import PipeSpec
from nmigen_lib.util import Main, delay


note_msg_spec = PipeSpec((
    ('onoff', unsigned(1)),
    ('channel', unsigned(4)),
    ('note', unsigned(7)),
    ('velocity', unsigned(7)),
))


class MIDIDecoder(Elaboratable):

    def __init__(self):
        self.serial_in = PipeSpec(8).outlet()
        self.note_msg_out = note_msg_spec.inlet()

    def elaborate(self, platform):

        def is_message_start(byte):
            # any byte with the high bit set
            return byte[7] != 0