Я пытаюсь выучить 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
порты.
Есть идеи о том, что мне здесь не хватает?