реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> Не работает модуль на verilog
Sprite
сообщение May 10 2018, 04:33
Сообщение #1


Частый гость
**

Группа: Участник
Сообщений: 154
Регистрация: 11-05-08
Пользователь №: 37 414



Доброго всем времени суток!
Прошу меня сильно не пинать, Verilog начал изучать совсем недавно. Модуль не хочет работать ни в симуляторе, ни в железе( Код программы, RTL и скрин симуляции прилагаются, могу скинуть исходный код. Проект собирается в Quartus II 9.1, ПЛИС cyclone III.
Код:
Код
module MEM_CONTROLLER
(
    input   clk, cs,
    input   [15:0] data_in,
    output  [15:0] data_out,
    output  reg [3:0] addr,
    output  wr
);
    reg [15:0] data_out_reg;
    reg [2:0] state;
    reg b_write;    //Если 1 - то записываем данные
    reg wr_reg;        

    parameter S0 = 0, S1 = 1, S2 = 2, S3 = 3, S4 = 4, S5 = 5, S6 = 6;

    always @ (posedge clk)
    begin
        case (state)
            
            //---------------------------
            // Ждем спад 1 cs
            //---------------------------
            S0:
                if (cs==0)
                    state <= S1;
                else
                    state <= S0;
            //---------------------------
            // Фронт 1 cs, заносим адрес в регистр addr
            // Если старший бит = 1 - то записываем данные в RAM,
            // иначе - читаем
            //---------------------------
            S1:
                if (cs)
                    begin
                        case (data_in[2:0])
                            3'b001  : addr <= 4'b0001;
                            3'b010  : addr <= 4'b0010;
                            3'b011  : addr <= 4'b0100;
                            3'b100  : addr <= 4'b1000;
                            default : addr <= 4'b0000;
                        endcase
                        
                        b_write <= data_in[15]? 1'b1:1'b0;
                        state <= S2;
                    end
                else
                    state <= S1;
            //---------------------------
            // Ждем спад 2 cs            
            //---------------------------
            S2:
                if (cs==0)
                    state <= S3;
                else
                    state <= S2;
            //---------------------------
            // Ждем фронт 2 cs
            //---------------------------
            S3:
                if (cs)
                    if (b_write)
                        begin
                            data_out_reg[15:0] <= data_in[15:0];
                            state <= S4;
                        end
                    else
                        state <= S0;    //Читаем данные (выводим их на data_out)
                else
                    state <= S3;
            //---------------------------
            // Ждем установки addr
            // Устанавливаем wr = 1
            //---------------------------        
            S4:
            begin
                wr_reg <= 1;
                state <= S5;
            end
            //---------------------------
            // Сбрасываем wr
            //---------------------------        
            S5:
            begin    
                wr_reg <= 0;
                state <= S0;
            end
            //---------------------------
        endcase
    end

    assign data_out[15:0] = data_out_reg[15:0];
    assign wr = wr_reg;

endmodule

RTL:

Waveform:


В симулиции по логике там где стоит маркер должен происходить переход в состояние S2, но ничего не происходит(
Go to the top of the page
 
+Quote Post
Flip-fl0p
сообщение May 10 2018, 05:01
Сообщение #2


В поисках себя...
****

Группа: Свой
Сообщений: 604
Регистрация: 11-06-13
Из: Санкт-Петербург
Пользователь №: 77 140



Цитата(Sprite @ May 10 2018, 07:33) *
Прошу меня сильно не пинать, Verilog начал изучать совсем недавно. Модуль не хочет работать ни в симуляторе, ни в железе

1. Я бы посоветовал проводить симуляцию не тем симулятором, который поставляется вместе с Quartus, а в таких симуляторах, как например, Modelsim или AtiveHDL. У всех есть бесплатные версии с ограничениями.
2. Начните описывать автоматы 3 классическими always блоками :
Первый блок синхронный - переключение состояний автомата.
Второй блок комбинационный - вычисление следующего состояния автомата.
Третий блок комбинационный - выходня логика автомата.
И лишь тогда, когда Вы научитесь правильно описывать автоматы таким стилем, только тогда переходите к другим стилям описания автомата. Сейчас Вы выбрали самый сложный стиль описания, где допустить ошибку очень и очень просто. А найти её, да ещё при использовании альтеровского симулятора, очень сложно.
3. Ну и присвойте нормальные имена состояниям автомата вместо:
Код
parameter S1 = 0, S1 = 1, S2 = 2, S3 = 3, S4 = 4, S5 = 5, S6 = 6;

Правильно присвоенные имена - очень помогают ориентироваться по коду ,особенно людям с ним незнакомым, а также избежать ошибок.
Go to the top of the page
 
+Quote Post
AVR
сообщение May 10 2018, 05:30
Сообщение #3


фанат Linux'а
*****

Группа: Свой
Сообщений: 1 254
Регистрация: 23-10-05
Из: SPB.RU
Пользователь №: 10 008



Цитата(Sprite @ May 10 2018, 07:33) *
Модуль не хочет работать ни в симуляторе, ни в железе

Не вижу ничего криминального, сам так пишу. Но вот какой смысл писать эти S0 S1,2...? Просто числа, либо идентификаторы. А тут можно просто числами ограничиться было.
Первое что заметил, в Verilog все имена зависят от высоты букв, поэтому разумеется что CS и cs это разные переменные для Verilog и в S2 мы так никогда и не попадем, хотя я не вижу код тестбенча, чтобы утверждать точно.
Далее, симулятор показывает белиберду в state.S0..N, почему нельзя просто вывести state ввиде числа и там было бы всё ясно и однозначно.
В общем, нужен опыт и всё станет хорошо.


--------------------
Go to the top of the page
 
+Quote Post
Sprite
сообщение May 10 2018, 06:29
Сообщение #4


Частый гость
**

Группа: Участник
Сообщений: 154
Регистрация: 11-05-08
Пользователь №: 37 414



Цитата(Flip-fl0p @ May 10 2018, 12:01) *
2. Начните описывать автоматы 3 классическими always блоками :
Первый блок синхронный - переключение состояний автомата.
Второй блок комбинационный - вычисление следующего состояния автомата.
Третий блок комбинационный - выходня логика автомата.
И лишь тогда, когда Вы научитесь правильно описывать автоматы таким стилем, только тогда переходите к другим стилям описания автомата. Сейчас Вы выбрали самый сложный стиль описания, где допустить ошибку очень и очень просто. А найти её, да ещё при использовании альтеровского симулятора, очень сложно.

А можно чуть подробнее? Для реализации state-машины я использовал стандартный шаблон автомата Мура:
Код
module four_state_moore_state_machine
(
    input    clk, in, reset,
    output reg [1:0] out
);

    // Declare state register
    reg        [1:0]state;

    // Declare states
    parameter S0 = 0, S1 = 1, S2 = 2, S3 = 3;

    // Output depends only on the state
    always @ (state) begin
        case (state)
            S0:
                out = 2'b01;
            S1:
                out = 2'b10;
            S2:
                out = 2'b11;
            S3:
                out = 2'b00;
            default:
                out = 2'b00;
        endcase
    end

    // Determine the next state
    always @ (posedge clk or posedge reset) begin
        if (reset)
            state <= S0;
        else
            case (state)
                S0:
                    state <= S1;
                S1:
                    if (in)
                        state <= S2;
                    else
                        state <= S1;
                S2:
                    if (in)
                        state <= S3;
                    else
                        state <= S1;
                S3:
                    if (in)
                        state <= S2;
                    else
                        state <= S3;
            endcase
    end

endmodule

Но здесь всего 2 блока: синхронный (Determine the next state) и комбинационный - вычисление следующего состояния автомата (Output depends only on the state). О каком третьем блоке Вы говорите? Насчет имен состояний полностью согласен - напишу что-нибудь более вразумительное.

Сообщение отредактировал Sprite - May 10 2018, 06:32
Go to the top of the page
 
+Quote Post
andrew_b
сообщение May 10 2018, 06:36
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 905
Регистрация: 30-12-04
Из: Воронеж
Пользователь №: 1 757



Цитата(Flip-fl0p @ May 10 2018, 08:01) *
Сейчас Вы выбрали самый сложный стиль описания, где допустить ошибку очень и очень просто.
Я придерживаюсь прямо противоположного взгляда. Ничего простого и удобного в размазывании КА по нескольким процессам не вижу.
Go to the top of the page
 
+Quote Post
Flip-fl0p
сообщение May 10 2018, 06:55
Сообщение #6


В поисках себя...
****

Группа: Свой
Сообщений: 604
Регистрация: 11-06-13
Из: Санкт-Петербург
Пользователь №: 77 140



Цитата(andrew_b @ May 10 2018, 09:36) *
Я придерживаюсь прямо противоположного взгляда. Ничего простого и удобного в размазывании КА по нескольким процессам не вижу.

У Вас опыта гораздо больше biggrin.gif.
Согласен, что несколько неудобно, т.к описание такого КА получается достаточно громоздким. Но при разделении автомата на 3 процесса - меньше шансов наделать ошибок, особенно это важно для начинающих. Считаю, что сначала надо научиться делать "классически" и "неудобно" - и когда будет полное понимание того, что происходит при описании автомата и в какую схему в итоге это выливается(да и вообще важно понимать что схемотехнически представляет собой цифровой автомат), тогда можно писать удобным для себя стилем, опять-же с полным пониманием зачем и почему.
Go to the top of the page
 
+Quote Post
Sprite
сообщение May 10 2018, 07:33
Сообщение #7


Частый гость
**

Группа: Участник
Сообщений: 154
Регистрация: 11-05-08
Пользователь №: 37 414



По совету Flip-fl0p переделал state-машину на 2 always-блока:
Код
module MEM_CONTROLLER
(
    input    clk, cs,
    input     [15:0] data_in,
    output     reg[15:0] data_out,
    output     reg[3:0] addr,
    output     reg wr
);
    reg [15:0] data_out_reg;
    reg [3:0] addr_reg;
    reg b_write;    //Если 1 - то записываем данные
    reg wr_reg;        
    
    initial
    begin
        data_out_reg = 15'b0;
        addr_reg = 4'b0;
    end
    
    
    reg    [2:0] state;
    parameter S0 = 0, S1 = 1, S2 = 2, S3 = 3, S4 = 4;


    // Output depends only on the state
    always @ (state, data_out_reg, addr_reg, data_in)
    begin
        case (state)
            S0,S1,S2,S3:
            begin
                data_out[15:0] = data_out_reg[15:0];
                addr[3:0] = addr_reg[3:0];
                wr = 1'b0;
            end
            S4:
            begin
                data_out[15:0] = data_in[15:0];
                addr[3:0] = addr_reg[3:0];
                wr = 1'b1;
            end    
            
            default:
            begin
                data_out[15:0] = 15'b0;
                addr[3:0] = 4'b0;
                wr = 1'b0;
            end
        endcase
    end


    always @ (posedge clk)
    begin
        case (state)
            
            //---------------------------
            // Ждем спад 1 cs
            //---------------------------
            S0:
                if (cs==0)
                    state <= S1;
                else
                    state <= S0;
            //---------------------------
            // Ждем фронт 1 cs, заносим адрес в регистр addr
            // Если старший бит в адресе = 1 - то записываем данные,
            // иначе - читаем
            //---------------------------
            S1:
                if (cs)
                    begin
                        case (data_in[2:0])
                            3'b001  : addr_reg <= 4'b0001;
                            3'b010  : addr_reg <= 4'b0010;
                            3'b011  : addr_reg <= 4'b0100;
                            3'b100  : addr_reg <= 4'b1000;
                            default : addr_reg <= 4'b0000;
                        endcase
                        
                        b_write <= data_in[15]? 1'b1:1'b0;
                        state <= S2;
                    end
                else
                    state <= S1;
            //---------------------------
            // Ждем спада 2 cs            
            //---------------------------
            S2:
                if (cs==0)
                    state <= S3;
                else
                    state <= S2;
            //---------------------------
            // Ждем фронт 2 cs
            //---------------------------
            S3:
                if (cs)
                    if (b_write)
                        state <= S4;
                    else
                        state <= S0;    //Читаем данные (выводим их на data_out)
                else
                    state <= S3;
            //---------------------------
            // Устанавливаем wr = 1
            //---------------------------        
            S4:
                state <= S0;
            //---------------------------
        endcase
    end

endmodule


В результате получилась более компактная и понятная RTL-схема:


И симуляция частично поправилась:

Только теперь значение data_out меняется только на момент состояния S4, при этом не сохраняя измененное значение ( Как это можно поправить?
Go to the top of the page
 
+Quote Post
one_eight_seven
сообщение May 10 2018, 07:43
Сообщение #8


Знающий
****

Группа: Участник
Сообщений: 859
Регистрация: 3-10-08
Из: Москва
Пользователь №: 40 664



Цитата
Только теперь значение data_out меняется только на момент состояния S4, при этом не сохраняя измененное значение ( Как это можно поправить?

Начать действовать последовательно и осмысленно.
Во-первых, если вы отлаживаете FSM, то нужно и смотреть FSM (регистр state), и входные сигналы, которые влияют на переход из одного состояния в другое.
Соответвствие выходов состоянию отладите позже.
Но если вы считаете, что автомат проходит по состояниям верно, то отлажвайте выходы. В вашем коде, в состояниях, кроме S4 data_out равно значению регистра, который инициализируется, но присваиваний которому не производится, т.е. он неизменный на протяжении работы системы, потому и data_out не изменяется. А в состоянии S4 сигналу data_out присваивается другое значение. То есть, всё работает так, как написано, и если вы хотите другого поведения, то его надо определить и описать в коде.

Сообщение отредактировал one_eight_seven - May 10 2018, 07:50
Go to the top of the page
 
+Quote Post
Flip-fl0p
сообщение May 10 2018, 07:45
Сообщение #9


В поисках себя...
****

Группа: Свой
Сообщений: 604
Регистрация: 11-06-13
Из: Санкт-Петербург
Пользователь №: 77 140



Цитата
Только теперь значение data_out меняется только на момент состояния S4, при этом не сохраняя измененное значение ( Как это можно поправить?

Потому-что data_out у вас мультиплексор, который в состоянии S4: выдает то, что на входе (data_in) :

Код
                data_out[15:0] = data_in[15:0];
                addr[3:0] = addr_reg[3:0];
                wr = 1'b1;


а в остальных состояниях выдает нули.

Код
            default:
            begin
                data_out[15:0] = 15'b0;
                addr[3:0] = 4'b0;
                wr = 1'b0;
            end


Делать надо немного по-другому. В состоянии S4 выдается сигнал разрешения записи в регистр:
Код
            S4:
            begin
                    write_ena = '1';
            end


И где-то описать эти регистры(Verilog только читаю, а не пишу на нем. Мог допустить ошибки. Передал суть):

Код
    always @ (posedge clk)
    begin
        if (write_ena)
            begin
                data_out[15:0] = 15'b0;
                addr[3:0] = 4'b0;
                wr = 1'b0;
            end
        
    end


Вот тут посмотрите : http://www.asic-world.com/tidbits/verilog_fsm.html
P.S. А почему такая старая версия Quartus ? Последняя версия, поддерживающая Cyclone III - Quartus 13.1.
Go to the top of the page
 
+Quote Post
bogaev_roman
сообщение May 10 2018, 07:49
Сообщение #10


Профессионал
*****

Группа: Свой
Сообщений: 1 078
Регистрация: 20-10-09
Из: Химки
Пользователь №: 53 082



to Sprite Посмотрел я на времянку и мозг отказал минут на 5 - как машина может находиться одновременно в нескольких состояниях? Там вообще мусор должен быть на моделировании - начальное состояние не определено - либо сброс добавьте, либо начальное условие при инициализации. Или это картинка не моделирования, а сигнал тап?
Go to the top of the page
 
+Quote Post
Sprite
сообщение May 10 2018, 08:10
Сообщение #11


Частый гость
**

Группа: Участник
Сообщений: 154
Регистрация: 11-05-08
Пользователь №: 37 414



Ошибся я немного. Переписал state-машину:
Код
    // Output depends only on the state
    always @ (state, data_out, addr_reg, data_in)
    begin
        case (state)
            S0,S1,S2,S3:
            begin
                data_out[15:0] = [b]data_out[15:0];[/b]
                addr[3:0] = addr_reg[3:0];
                wr = 1'b0;
            end
            S4:
            begin
                data_out[15:0] = data_in[15:0];
                addr[3:0] = addr_reg[3:0];
                wr = 1'b1;
            end    
            
            default:
            begin
                data_out[15:0] = 15'b0;
                addr[3:0] = 4'b0;
                wr = 1'b0;
            end
        endcase
    end

Вместо data_out_reg[15:0] нужно было делать присвоение data_out[15:0] < data_out[15:0]. Естественно все заработало) Только вылезла целая куча варнингов, типа:
Код
Warning (10240): Verilog HDL Always Construct warning at MEM_CONTROLLER.v(27): inferring latch(es) for variable "data_out", which holds its previous value in one or more paths through the always construct

Как я понял квартус ругается на наличие latch, но именно так я и планировал.

RTL-схема:


и правильный waveform:



Конечно, некрасиво с варнингами, буду думать как устранить.
Go to the top of the page
 
+Quote Post
Flip-fl0p
сообщение May 10 2018, 08:13
Сообщение #12


В поисках себя...
****

Группа: Свой
Сообщений: 604
Регистрация: 11-06-13
Из: Санкт-Петербург
Пользователь №: 77 140



Код
Как я понял квартус ругается на наличие latch, но именно так я и планировал.

А Вы читали, что я Вам писал ?
Latch - в 99% случаев это ошибка. Вы пытаетесь в комбинационном блоке сохранить значения. Ну Qurtus и сделал Вам защелку, как Вы и просили его.
Go to the top of the page
 
+Quote Post
Sprite
сообщение May 10 2018, 08:38
Сообщение #13


Частый гость
**

Группа: Участник
Сообщений: 154
Регистрация: 11-05-08
Пользователь №: 37 414



Цитата(Flip-fl0p @ May 10 2018, 15:13) *
Код
Как я понял квартус ругается на наличие latch, но именно так я и планировал.

А Вы читали, что я Вам писал ?
Latch - в 99% случаев это ошибка. Вы пытаетесь в комбинационном блоке сохранить значения. Ну Qurtus и сделал Вам защелку, как Вы и просили его.


Поправил) Вынес защелку в отдельный блок:
Цитата
module MEM_CONTROLLER
(
input clk, cs,
input [15:0] data_in,
output [15:0] data_out,
output [3:0] addr,
output wr
);
reg [15:0] data_out_reg;
reg [3:0] addr_reg;
reg b_write; //Если 1 - то записываем данные
reg wr_reg;

initial
begin
data_out_reg = 15'b0;
addr_reg = 4'b0;
end


reg [2:0] state;
parameter S0 = 0, S1 = 1, S2 = 2, S3 = 3, S4 = 4, S5 = 5;

always @ (posedge clk)
begin
case (state)

//---------------------------
// Ждем спад 1 cs
//---------------------------
S0:
if (cs==0)
state <= S1;
else
state <= S0;
//---------------------------
// Ждем фронт 1 cs, заносим адрес в регистр addr
// Если старший бит в адресе = 1 - то записываем данные,
// иначе - читаем
//---------------------------
S1:
if (cs)
begin
case (data_in[2:0])
3'b001 : addr_reg <= 4'b0001;
3'b010 : addr_reg <= 4'b0010;
3'b011 : addr_reg <= 4'b0100;
3'b100 : addr_reg <= 4'b1000;
default : addr_reg <= 4'b0000;
endcase

b_write <= data_in[15]? 1'b1:1'b0;
state <= S2;
end
else
state <= S1;
//---------------------------
// Ждем спад 2 cs
//---------------------------
S2:
if (cs==0)
state <= S3;
else
state <= S2;
//---------------------------
// Ждем фронт 2 cs, устанавливаем wr_reg
//---------------------------
S3:
if (cs)
if (b_write)
state <= S4;
else
state <= S0; //Читаем данные (выводим их на data_out)
else
state <= S3;
//---------------------------
// Устанавливаем wr_reg
//---------------------------
S4:
begin
wr_reg <= 1'b1;
state <= S5;
end
//---------------------------
// Сбрасываем wr_reg
//---------------------------
S5:
begin
wr_reg <= 1'b0;
state <= S0;
end
//---------------------------
endcase
end

//---------------------------
// Блок-защелка данных
//---------------------------
always @ (posedge clk)
begin
if (state == S4)
data_out_reg[15:0] = data_in[15:0];
end


//---------------------------
assign data_out = data_out_reg;
assign addr = addr_reg;
assign wr = wr_reg;
//---------------------------
endmodule


RTL-схема:



И нерабочий Waveform:



В итоге пришел к самому первому варианту( Один большой плюс: варнинги исчезли))

Сообщение отредактировал Sprite - May 10 2018, 08:39
Go to the top of the page
 
+Quote Post
Marat Zuev
сообщение May 10 2018, 08:56
Сообщение #14


Участник
*

Группа: Участник
Сообщений: 28
Регистрация: 8-05-18
Пользователь №: 103 834



Цитата(Sprite @ May 10 2018, 09:38) *
Код
//---------------------------
// Блок-защелка данных
//---------------------------
always @ (posedge clk)
begin
  if (state == S4)
    data_out_reg[15:0] = data_in[15:0];
end
Это - не защёлка, а 15 параллельных триггеров:
Код
always @ (posedge clk)
    data_out_reg = state == S4 ? data_in : data_out_reg;

А, вообще, давайте Ваш проект (тем более, что он небольшой) сюда (с тестбенчем, конечно): будет время - можно повозиться.


--------------------
--
С наилучшими пожеланиями, Marat.
Go to the top of the page
 
+Quote Post
Sprite
сообщение May 10 2018, 09:19
Сообщение #15


Частый гость
**

Группа: Участник
Сообщений: 154
Регистрация: 11-05-08
Пользователь №: 37 414



Цитата(Marat Zuev @ May 10 2018, 15:56) *
Это - не защёлка, а 15 параллельных триггеров:
Код
always @ (posedge clk)
    data_out_reg = state == S4 ? data_in : data_out_reg;

А, вообще, давайте Ваш проект (тем более, что он небольшой) сюда (с тестбенчем, конечно): будет время - можно повозиться.


Проект Во вложении. entity - test3.qpf Собирал в Quartus II 9.1, использовал для теста встроенный симулятор (файл test3.vwf)

Сообщение отредактировал Sprite - May 10 2018, 09:20
Прикрепленные файлы
Прикрепленный файл  cyclone_III.rar ( 2.24 мегабайт ) Кол-во скачиваний: 4
 
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 27th May 2018 - 21:15
Рейтинг@Mail.ru


Страница сгенерированна за 0.01149 секунд с 7
ELECTRONIX ©2004-2016