Почему Xilinx ISE не делает вывод о блочной ОЗУ?

Как следует из названия, у ISE возникают проблемы с выводом блочного ОЗУ из моего кода.

wire we;

reg hold = 0;
reg start = 0;

reg [12:0] addr = 0;
reg [23:0] command = 0;

reg [7:0] RAM [8191 : 0];

reg [7:0] rx_data_buffer = 0;

assign we = new_rx_data && !hold && start;

always@(posedge clk) begin

new_tx_data <= 1'b0;

if(!tx_busy && hold && !new_tx_data) begin

    new_tx_data <= 1'b1;        
    addr <= addr + 1'b1;

    tx_data_buffer <= RAM[addr];

    if(addr == 13'd8191)
        hold <= 0;

end

else if(new_rx_data && !hold) begin

    addr <= addr + 1'b1;
    command <= {command[15:0], rx_data};

    if(addr == 13'd8191)
        hold <= 1;

    if(start)
        led <= rx_data;

end

if(we)
    RAM[addr] <= rx_data;

if(command == 24'h242424) //$$$ in ASCII
    start <= 1;

end

Я пришел к выводу, что корень проблемы - это сигнал разрешения записи для моей оперативной памяти. Если я установлю VCC, написав

if(1'b1)
    RAM[addr] <= rx_data;

ISE выводит RAM без проблем. Однако это не мое предполагаемое поведение. Я хочу, чтобы сигнал разрешения записи был

assign we = new_rx_data && !hold && start;

Независимо от того, какой регистр я назначаю «мы», ISE сообщает мне, что будет предполагать распределенную оперативную память. Кто-нибудь раньше занимался этим вопросом?


person Cedric Orban    schedule 02.11.2016    source источник


Ответы (1)


У вас есть пара вещей, которые, вероятно, нужно решить. Я вижу, вы используете new_rx_data для назначения нам. Я не вижу, чтобы это было назначено в вашем RTL. Он плавает? или вход?

Адрес назначается в IF и ELSEIF. ELSE нет, поэтому, на мой взгляд, это означает, что он не назначается при некоторых условиях. Может быть, он просто сохраняет ценность, но опять же, я не предпочитаю это делать.

Другой заключается в том, что вы назначаете с использованием неблокирующих назначений и потенциально назначаете одну и ту же переменную дважды (см. New_tx_data), и я не могу быть уверен, как это будет синтезироваться. Если он несинтезируемый, я надеюсь, что сборка выйдет из строя, но при сборке вы можете получить неожиданные результаты.

При этом вам необходимо исправить эти вещи, чтобы результаты моделирования соответствовали реальным результатам. Вы симулятор, который говорит, что странные назначения мячей - это нормально, и инструмент физического синтеза, который решает проблему по-другому, два результата, вероятно, будут разными.

Итак, второе, что вам нужно сделать, это проверить свои предупреждения. Инструмент синтеза будет жаловаться на вещи и может включать в себя неприятные предупреждения о некоторых сигналах, с которыми вы работаете. Если один из сигналов, с которыми вы работаете (проверьте эти три сигнала в своем операторе assign we), как утверждается, всегда застревает на высоком уровне или всегда застревает на низком уровне, у вас может быть состояние, которое означает, что вы не можете писать, или вы можете '' t читать, или и то, и другое. Это приведет к тому, что RAM не будет выводиться. Нет смысла делать память, которая не может записывать, верно? Вы всегда будете читать нули, поэтому я просто подключу для вас шину данных к нулю и покончим с этим.

person Rich Maes    schedule 03.11.2016
comment
Привет, спасибо за ответ. Из того, что я помню о стандарте Verilog, сигналы, назначенные в разных местах поведенческого блока, будут принимать значение последнего назначения в блоке. Это определенно поддерживается как инструментами синтеза, так и моделирования. Сигналы, которые не назначены явно, также сохранят свои значения. Предупреждение о синтезе не помогло, поскольку я мог использовать асинхронное чтение. Настоящая проблема заключалась в том, что я использовал один и тот же адрес для чтения и записи (не знаю почему). Использование разных регистров для этих значений устранило проблему. - person Cedric Orban; 04.11.2016
comment
Разве это не приведет к возникновению защелок и, возможно, к несоответствию симуляции / синтеза? Они, как я сделал это выше, просто сделают вывод о триггере с логическим элементом И перед входом. - person Cedric Orban; 04.11.2016
comment
Вы можете безопасно выполнять несколько назначений с назначением блокировки, например =, чтобы получить порядок последовательного разрешения, как вы ожидаете, но вы не должны использовать неблокирующее ‹= таким образом, поскольку это создает состояние гонки. Состояние гонки могло разрешиться неожиданными способами. По сравнению с тем, чтобы не назначать все во всех случаях, это скорее придирка, но когда вы не знаете, что происходит, вы можете подумать о том, чтобы быть более конкретным. - person Rich Maes; 04.11.2016
comment
Не знаю, поможет это или нет, но вот ссылка на другой вопрос о предполагаемые защелки. Здесь также есть кое-что об использовании блокирующих назначений по сравнению с неблокирующими. - person Rich Maes; 04.11.2016
comment
Я считаю, что у вас все наоборот. Назначения блокировки гораздо более подвержены условиям гонки при использовании в синхронизированных поведенческих блоках. Взгляните: vlsiencyclopedia.com/2012/08/race- condition-in-verilog.html - person Cedric Orban; 04.11.2016
comment
Я согласен с этим утверждением. Но в приведенном выше коде вы потенциально назначаете одну и ту же переменную дважды за одни и те же часы, используя неблокирующее присвоение. Это создает состояние гонки. Поскольку у вас есть то, что выглядит как назначение по умолчанию, это похоже на блокирующую архитектуру, реализованную в синхронизированном процессе. - person Rich Maes; 04.11.2016