Jump to content

    
Грендайзер

VERILOG, тест бенч и не только

Recommended Posts

Здравствуйте. Начал изучать VERILOG :mad: Господи... зачем его придумали это ж... :twak: Извиняюсь... Вообщем надо написать несложный тестбенч, но выискивать эти конструкции этого с позволения сказать языка (я б даже сказал суржика ей богу) честно говоря устал... Есть файлик .txt в нём сложены слова. Надо их считать из файла и выдать на шину данных по спадающему фронту тактового сигнала. Считать считал, но как выдать... при том, что бы это выдача была бы зациклена. То есть в VHDL мне достаточно был определить параметры тактового сигнала и в process по необходимому фронту клока выдавать данные инкрементируя какой нить счётчик. И всё... Привиду отрывочек кода, который смог наваять:

reg [5:0] v_mem [0:7];
integer i;
    
        always
        begin
        clk = 1'b1;
        #10;
        clk = 1'b0;
        #10;
        end        
        
        initial 
        begin
        reset = 1'b1;
        #50;
        reset = 1'b0;
        end
        
        initial 
        begin
        $display("simulate start");    
        $readmemb("vector.txt", v_mem);
        $display("simulate file_read");
        
        always@(negedge clk)
        begin
        i <= i + 1;
        din <= v_mem [i];
        end

        end
        
        endmodule

 

И ещё 2 вопроса. Может кто нибудь объяснить, нафиг нужен wire, если как я понял, его может и reg заменить? И ещё в чём разница между "=" и "<=". Я сначала думал это типо как константы и сигналы в VHDL, но нет блин...

Edited by Грендайзер

Share this post


Link to post
Share on other sites

wire - это провод. Для соединения блоков и для выражения комбинационной логики.

reg - может выражать последовательностную схему, а может комбинационную схему в зависимости от написания.

подробнее можно прочитать тут https://habrahabr.ru/post/306982/

<= и = это неблокирующее и блокирующее присваивание. Основное правило - первое мы применяем в последовательностной логике, а второе в комбинационной.

 

по фронту выдачу можно организовать что-то типа такого :

пишем цикл нужный http://www.asic-world.com/verilog/verilog_one_day2.html вот тут

затем туда вставляем фронт (@negedge clk)

и выдаем данные - вот тут смотрите http://www.angelfire.com/in/verilogfaq/pli.html

 

Share this post


Link to post
Share on other sites

Большое спасибо. Почитаю.

 

Подскажите ещё пожалуйста.

Есть регистр reg reg [5:0] shift_reg [7:0]. В него по шине datain загоняюся данные следующим образом

always @(posedge clk, posedge reset)
begin
    if (reset) 
    begin
        for(i=0; i<16; i=i+1) 
          sr[i] <= 6'b000000;
    end
    else 
    begin
        for(i=7; i>0; i=i-1) 
        begin
                shift_reg[i] <= shift_reg[i-1];
        end    
        shift_reg[0] <= datain;
    end
end

И есть выходной порт wire [15:0] dout такой что

assign dout = shift_reg[15] + shift_reg[14] + shift_reg[13] +...

Писать этот сумматор в ручную как то не элегантно... Подскажите как это сделать. Я так понимаю, что с помощью for(i = 0...) но куда эту конструкцию сунуть? Как я понимаю надо как то к always прикрутить, но как...

Edited by Грендайзер

Share this post


Link to post
Share on other sites

sr в ветке положительного резета есть shift_reg?

 

вторую часть можно написать элегантнее:

 

shift_reg <= {shift_reg[6:0], datain};

без всяких циклов.

 

Я немного не понял, вы хотите просуммировать биты в регистре или просуммировать массив регистров?

Share this post


Link to post
Share on other sites
sr в ветке положительного резета есть shift_reg?

Да. Описался =)

Я немного не понял, вы хотите просуммировать биты в регистре или просуммировать массив регистров?

Я бы хотел просуммировать все регистры входящие в массив shift_reg, т.е. assign dout = shift_reg[15] + shift_reg[14] + shift_reg[13] +... Т.е. сумматор строится на комбинационной логике. В вхдл это делается с помощью цикла for .... loop. Но в верилоге не догоню чего то...

P.S.

shift_reg <= {shift_reg[6:0], datain} так тоже можно?! Спасибо.

Edited by Грендайзер

Share this post


Link to post
Share on other sites

shift_reg <= {shift_reg[6:0], datain} это вместо

for(i=7; i>0; i=i-1)

begin

shift_reg <= shift_reg[i-1];

end

shift_reg[0] <= datain;

 

 

А shift_reg в массиве знаковые или беззнаковые? И их точно 16 штук или согласно 3 сообщению 6? и массив из 16 слов по 8 бит в верилоге это reg [7:0] array[0:15];

в общем случае это вот так по идее

reg [15:0] dout; // в нашем случае это как провод, а не регистр

integer i;

 

always@*

begin

for(i = 0; i < 16; i = i + 1)

begin

dout = dout + shift_reg;

end

end

но вообще это очень плохо, так как получится слишком большой сумматор из 16 ступеней что приведет к большим propogational delay скорей всего и частота работы схемы снизится

Share this post


Link to post
Share on other sites
А shift_reg в массиве знаковые или беззнаковые?

Знаковые. А в верилоге можно как то компилятору сказать, что числа знаковые или беззнаковые? Я как понял в нём только wire, reg и integer.

Share this post


Link to post
Share on other sites

можно. по умолчанию все числа беззнаковые.

но есть волшебное слово signed, пишем после reg или wire.

Результат тоже должен быть знаковый?

Если знаковые, то в верилоге результат, который имеет разрядность 16 бит и регистры которые имеют разрядность 8 бит приведутся к 16 бит, причем недостающие биты заполнятся нулями. Нужен sign extension(в той книге есть)

Share this post


Link to post
Share on other sites
Знаковые. А в верилоге можно как то компилятору сказать, что числа знаковые или беззнаковые? Я как понял в нём только wire, reg и integer.

Можно сказать, что знаковые.

И по поводу суммирования - странный у Вас способ.

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

Share this post


Link to post
Share on other sites

и если честно я что то не понял.

16 элементов массива.

Входные данные datain входят в нулевой элемент массива который 1 байт, а остальные сдвигаются?

Или в одном слове массива происходит прием datain со сдвигом?

Share this post


Link to post
Share on other sites
Суммирование надо производить прямо в темпе приема. Прием - битовый, вот и сумматор должен быть битовый... При этом ресурса задействуются крохи...

Пожалуй Вы правы.

_Ivan_33, iosifk, большое спасибо за помощь.

Share this post


Link to post
Share on other sites
Здравствуйте. Начал изучать VERILOG :mad: Господи... зачем его придумали это ж... :twak: Извиняюсь... Вообщем надо написать несложный тестбенч, но выискивать эти конструкции этого с позволения сказать языка (я б даже сказал суржика ей богу) честно говоря устал...
Можно ненавидеть двухколесные велосипеды за то что с них падают в начале, но шоссейные гонки на трехколесных я не видел...

 

       
         integer i;
initial
        begin
        $display("simulate start");    
        $readmemb("vector.txt", v_mem);
        $display("simulate file_read");
        
        for(i = 0; i < 100; i = i + 1)
        begin
                din <= v_mem [i];
                @(negedge clk);
        end

end

Share this post


Link to post
Share on other sites

Да там чёрт голову сломит. Ну ей богу дня 3 с ним сижу и не увидел преимуществ перед вхдл. Пока у меня количество писанины не сильно уменьшилось, а вот наглядность вообще ускакала. И вообще... меня терзают смутные сомнения, что причина появления верилога это не желание некоторых любителей С учить новый язык, да ещё и при том, не имеющий с C ничего общего (при том не только по синтаксису но и по сути).

P.S.

В итоге с тестом решил задачу в лобешник.

    @(negedge reset)
        
        test_reg = -test_reg;
        
        repeat(100) begin
        @(negedge clk)
        din <= v_mem [i];
        i <= i - 1;
        end

Edited by Грендайзер

Share this post


Link to post
Share on other sites

Снова здравствуйте. В моём коде есть такой кусочек:

assign m[0] = (PRBS[0]) ? -sr[0]:sr[0];
assign m[1] = (PRBS[1]) ? -sr[1]:sr[1];
assign m[2] = (PRBS[2]) ? -sr[2]:sr[2];
........................................................

Хочется поэлегантней, я записал вот так:

 

always@*
begin
for(l=0; l<16; l=l+1)
m[l] = (PRBS[l]) ? -sr[l]:sr[l];
end

 

Но ISE выдаёт ошибку:

ERROR:Xst:902 - "Trig_my.v" line 33: Unexpected sr event in always block sensitivity list.

В чём дело?

Share this post


Link to post
Share on other sites
... в чём разница между "=" и "<=". Я сначала думал это типо как константы и сигналы в VHDL, но нет блин...

Этот вопрос меня насторожил - неужели в VHDL нет аналога Верилоговского блокирующего и неблокирующего присваивания?

VHDL не знаю, сейчас посмотрел поверхностно - вроде как <= для сигналов, и := для переменных и являются аналогами неблокирующего и блокирующего присваиваний.

Так это, или нет?

Был бы благодарен, если кто-то даст сравнение VHDL и Verilog по блокирующим/неблокирующим присваиваниям - в плане принципиальных отличий.

Edited by Leka

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.