Как получить входную шину в MyHDL? - PullRequest
0 голосов
/ 30 ноября 2018

Я пытаюсь выучить MyHDL, и для этого я пытался создать очень простой искусственный нейрон, который позже мог бы использоваться в простой искусственной нейронной сети.Сначала я разработал искусственный нейрон, который мог обрабатывать только один входной и весовой сигналы и возвращал выходной сигнал.

@block
def input_perceptron(clk, max_res, in_signal, w_signal, out_signal):
    '''a hidden layer neuron
    out_signal is the result of: transfer_function( input_i x weight_i )
    '''
    @always(clk.posedge)
    def logic():
        # Multiply inputs and scale down with the shift
        weighted_signal = (in_signal * w_signal) >> max_res+1
        # Perform desired transfer function
        tf_result = rect_transfer_func( weighted_signal, max_res )
        # Assign new result
        out_signal.next = tf_result
    # The perceptron block must return this - MyHDL syntax
    return instances()

Чтобы преобразовать его в Verilog, я использовал другую функцию:

def converter(max_res=16, hdl='Verilog'):
    # Initialize Signals
    max_val    = 1 << max_res + 1
    clk        = Signal( bool(0) )
    in_signal  = Signal( intbv( randrange(max_val), min=0, max=max_val ) )
    w_signal   = Signal( intbv( randrange(max_val), min=0, max=max_val ) )
    out_signal = Signal( intbv( 0,                  min=0, max=max_val ) )
    # Instantiate component
    perceptron_inst = input_perceptron(clk, max_res, in_signal, w_signal, out_signal)
    # Convert component to desired HDL language
    perceptron_inst.convert(hdl=hdl)

Пока все шло отлично.Мало того, что моделирование показало мне то, что я ожидал, но и преобразованный код был верным, и я смог синтезировать его в Vivado.Однако в нейронной сети нейроны скрытого и выходного слоев должны быть способны обрабатывать информацию, поступающую из нескольких источников, то есть списка или шины сигналов, и именно здесь у меня возникают проблемы.

Используя удивительные функции MyHDL и Python для запуска симуляции, я смог правильно смоделировать простой персептрон со следующим кодом, используя списки сигналов для входов и весов:

@block
def perceptron(clk, max_val, max_res, in_bus, w_bus, out_signal):
    ''' Perceptron
    out_signal is the result of: transfer_function( sum( input_i x weight_i ) )
    '''
    @always(clk.posedge)
    def logic():
        # Multiply inputs and scale down
        sum_weighted_inputs = 0
        for i in range(len(in_bus)):
            weighted_input = in_bus[i] * w_bus[i] >> max_res+1
            sum_weighted_inputs += weighted_input
        # Perform desired transfer function
        tf = step_transfer_func(sum_weighted_inputs, max_res, max_val)
        # Assign new result to ouput port
        out_signal.next = tf
    return instances()

Послепросматривая документы ( документы ), я понял, что в MyHDL блок не может использовать список сигналов в качестве порта, и что согласно этой главе я должен преобразовать свой списоксигналы в ConcatSignal, который я сделал так:

def converter(max_res, num_inputs, hdl='Verilog'):
    # Clock parameters
    clk        = Signal( bool(0) )
    # Signal parameters: inputs, weights and outputs
    max_val    = 1 << max_res + 1
    out_signal = Signal( intbv( 0, min=0, max=max_val )[max_res+1:] )
    in_list    = [Signal( intbv( randrange(max_val), min=0, max=max_val )[max_res+1:] ) for i in range(num_inputs)]
    w_list     = [Signal( intbv( randrange(max_val), min=0, max=max_val )[max_res+1:] ) for i in range(num_inputs)]
    # Converting to a bus in HDL
    input_bus  = ConcatSignal(*reversed(in_list))
    weight_bus = ConcatSignal(*reversed(w_list))
    # Instantiate component
    perceptron_inst = perceptron(clk, max_val, max_res, input_bus, weight_bus, out_signal)
    # Convert component to desired HDL language
    perceptron_inst.convert(hdl=hdl)

Когда я пытаюсь смоделировать дизайн, все работает как положено, однако при преобразовании возникает небольшая ошибка: входы in_bus и w_busПерцептрон определяется в Verilog как output порты вместо input портов.Как следствие этого 2 wires для этих портов также генерируются, и им присваивается значение None.

Интересным моментом является то, что остальная часть кода Verilog верна, и если я простоудалите сгенерированное присвоение wires и None, и если я вручную изменю output на input для in_bus и w_bus в файле Verilog, то код будет синтезируемым.Если я посмотрю на разработанный дизайн Vivado после этих изменений, то модуль, похоже, будет именно тем, что я хотел.

Хотя я мог бы вручную исправить эту проблему в файлах Verilog, я чувствую, что эта проблема возникла из-за неправильного использования / отсутствияпонимания MyHDL с моей стороны.Я не могу понять, почему использование ConcatSignal внезапно превращает порты input в output порты.

Есть идеи о том, что мне здесь не хватает?

1 Ответ

0 голосов
/ 03 декабря 2018

Вы не можете использовать список сигналов в качестве порта верхнего уровня, вам нужно создать оболочку с одним входом, которая создаст ваш список сигналов, после чего он может быть передан универсальному.

...