Jump to content

    
zombi

Как в плис реализовать триггер защёлку по уровню?

Recommended Posts

Все заняты. Понятно.

Правда к конечному автомату это, по моему, никакого отношения не имеет, но вроде работает как на диаграмме.

Гляньте не накосячил чего?

 

module myshift (input res,clk,EV,output reg [7:0] q);
	wire sEV = EV | ~q[7];
always @(posedge clk)
	if (res) q = 8'b10000000;
	else if (sEV) begin
		q[0]<=q[7];
		q[1]<=q[0];
		q[2]<=q[1];
		q[3]<=q[2];
		q[4]<=q[3];
		q[5]<=q[4];
		q[6]<=q[5];
		q[7]<=q[6];
	end
endmodule

 

Share this post


Link to post
Share on other sites
9 hours ago, zombi said:

Гляньте не накосячил чего?

не нравится мне 

wire sEV = EV | ~q[7];

При EV в 1 регистр по диаграмме не сдвигает.

 

Похоже - всё же нужен автомат, который после спада EV начинает считать до 80, потом смотрит EV - если еще не 1, то ждет ее.

И еще - что должно произойти, если EV в процессе счета (сдвига) снова успеет упасть в 0?

Edited by Yuri124

Share this post


Link to post
Share on other sites
module myshift (input reset_sys_n, clock_sys, ev, output reg [7:0] q);
	
reg [4:0] state, next_state;
parameter IDLE     = 0,
          STATE_01 = 1,
          STATE_02 = 2,
          STATE_04 = 3,
          STATE_08 = 4,
          STATE_10 = 5,
          STATE_20 = 6,
          STATE_40 = 7,
          STATE_80 = 8;

always @ (posedge clock_sys or negedge reset_sys_n)
        if (! reset_sys_n) state <= IDLE;
        else state <= next_state;



always @ (*)
        begin
           //next_state = 'bx;
                        
            case (state)
            
                IDLE:       begin
                               if (ev) next_state = IDLE;
                               else next_state = STATE_01;
                            end
               STATE_01:  next_state = STATE_02;
               STATE_02:  next_state = STATE_04;
               STATE_04:  next_state = STATE_08;
               STATE_08:  next_state = STATE_10;
               STATE_10:  next_state = STATE_20;
               STATE_20:  next_state = STATE_40;
               STATE_40:  next_state = STATE_80;
               STATE_80:  begin
                               if (ev) next_state = IDLE;
                               else next_state = STATE_80;
                          end

               default: next_state = IDLE;
            endcase
        end

always @ (posedge clock_sys or negedge reset_sys_n)
            if (! reset_sys_n)    begin
                                        q <= 8'b10000000;   
                                  end
            else
                                        
                    case (next_state)
                    
                        IDLE:     ;
                        STATE_01: q <= {q[6:0], q[7]};
                        STATE_02: q <= {q[6:0], q[7]};
                        STATE_04: q <= {q[6:0], q[7]};
                        STATE_08: q <= {q[6:0], q[7]};
                        STATE_10: q <= {q[6:0], q[7]};
                        STATE_20: q <= {q[6:0], q[7]};
                        STATE_40: q <= {q[6:0], q[7]};
                        STATE_80: q <= 8'b10000000;       
                                          
                    endcase
                //end 

endmodule

 

Ну, как-то так. В зависимости от

2 hours ago, Yuri124 said:

что должно произойти, если EV в процессе счета (сдвига) снова успеет упасть в 0?

можно поправить процесс "вычисления" следующего состояния в блоке always @ (*)

Также - если EV даст команду на новый счет в состоянии автомата STATE_80, то автомат это не заметит и пропустит цикл счета.

Edited by Yuri124

Share this post


Link to post
Share on other sites
1 hour ago, Yuri124 said:

При EV в 1 регистр по диаграмме не сдвигает.

Всё верно. Я просто пока сделал в блок-схеме выделение фронта спада EV и уже этот сигнал подал на myshift.

До выделения фронта сигнала на верилоге пока не дошел. (

Это моя первая попытка (может и последняя, а может и нет) чего-то на V написать. Не судите строго.

Share this post


Link to post
Share on other sites

Еще раз гляньте мой предыдущий пост - в конце дописал пару строк.

4 minutes ago, zombi said:

Это моя первая попытка (может и последняя, а может и нет) чего-то на V написать.

Уверен - забудете рисовать схемы как страшный сон.

(я так ни одной и не нарисовал, даже инвертора)  :)

Share this post


Link to post
Share on other sites
40 minutes ago, Yuri124 said:


 

Ну, как-то так.

Что-то ну уж слишком сложно. Это же по большому счёту просто циклический сдвиговый регистр с хитрым запуском и остановкой )

Share this post


Link to post
Share on other sites
4 minutes ago, zombi said:

уж слишком сложно

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

 

Специально Вам с тремя написал - для ознакомления. Вы ту доку почитайте, что я давал ссылку (сделано по ней) - один раз поймете, зачем так придумали писать - и понравится.

Там фишка в том, что в блоке (втором, со звездочкой) вычисляется next_state, а по тексту (в третьем always блоке) - сразу видно, какие сигналы на выходе в этом состоянии будут. Очень удобно.

Третий блок (для разнообразия) можно изобразить так:

 

always @ (posedge clock_sys or negedge reset_sys_n)
            if (! reset_sys_n)    begin
                                           q <= 8'b10000000;   
                                        end
            else
                begin 

                     q <= 8'b00000000;  

                      
                    case (next_state)
                    
                        IDLE:         q[7] <= 1'b1;
                        STATE_01:  q[0] <= 1'b1;
                        STATE_02:  q[1] <= 1'b1;
                        STATE_04:  q[2] <= 1'b1;
                        STATE_08:  q[3] <= 1'b1;
                        STATE_10:  q[4] <= 1'b1;
                        STATE_20:  q[5] <= 1'b1;
                        STATE_40:  q[6] <= 1'b1;
                        STATE_80:  q[7] <= 1'b1;
                                         
                    endcase

            end

Share this post


Link to post
Share on other sites

Вот так вот выделил фронт в рассыпухе.

Теперь надо это всё (что слева от myshift) добавить к модулю на верилоге. Поможете?

D.jpg

8 minutes ago, Yuri124 said:

Можно упростить до двух always блоков, или даже сделать в одном всё.

Обязательно буду разбираться, но попозже (

Share this post


Link to post
Share on other sites

А зачем добавлять? Я сделал по Вашей времянке сигналов, там - уже выделение спада EV как-бы автоматически появилось - разберитесь обязательно с обоими вариантами моей писанины.

Нюанс последнего варианта - то, что "как-бы" сначала вых регистр устанавливает в 0 все выходы. Но на самом деле этого не происходит - в зависимости от состояния одна единичка всегда на одном из выходов тут же пишется.

Такое написание - для того, чтобы только в нужном состоянии нужная лог. 1 появилась, а в другом состоянии она автоматически сбросится - т.е. за этим не нужно специально следить.

Похоже, я лишний end всунул (делал на основе другого автомата, не заметил лишнее) - закомментировал его. 

Edited by Yuri124

Share this post


Link to post
Share on other sites
2 hours ago, Yuri124 said:

Похоже, я лишний end всунул (делал на основе другого автомата, не заметил лишнее) - закомментировал его. 

Да, это ерунда ква сразу руганулся и я его убрал.

--------------------------------------------------------

Вот провёл три теста для реального чипа.

Взял самый простой и самый медленный из cpld MAXII (EPM240T100C5).

Из всех вх/вых подключил только клок на dedicatd pin, и оптимизация speed.

У всех вариантов функциональные временные диаграммы абсолютно одинаковые, но есть отличия по максимальной частоте и занимаемым ресурсам.

 

Тест 1. ==================================================

STATE machine от Yuri124

Total logic elements 18 / 240 
Fmax summary 224.42 MHz

 

Test 2.==================================================

Таки добавил детектор фронта к своему модулю shift.

Если накосячил или перемудрил чего, поправьте пожалуйста.

module myshiftNEW (input res,clk,EV,output reg [7:0] q);
	wire A1 = !EV;
	reg  A2;
	wire A3 = A1 & A2;
	wire sEV = A3 | !q[7];
always @(posedge clk) A2 <= EV;
always @(posedge clk)
	if (!res) q = 8'b10000000;
	else if (sEV) q <= {q[6:0], q[7]};
endmodule

Total logic elements 10 / 240 
Fmax summary 267.17 MHz

 

Тест 3.==================================================

Опять вернулся к блок схеме и нарисовал вот это :

E.jpg

Total logic elements 9 / 240 
Fmax summary 266.74 MHz

Share this post


Link to post
Share on other sites

Сразу возникли вопросы:

1.Кто объяснит почему такая  сильная разница между машиной состояний и просто сдвиговым регистром?

2.Кто может помочь описать схему из третьего теста на верилоге?

Share this post


Link to post
Share on other sites
1 hour ago, zombi said:

У всех вариантов функциональные временные диаграммы абсолютно одинаковые

Это вряд ли. 

Попробуйте сделать такой тест  во всех вариантах: когда EV запустит работу сдвигового регистра - пока еще не сдвинул 1 до конца (до 7-го разряда) - еще раз запустите EV. 

Например: 1. Старт EV

2. Сдвинул 2 раза

3. снова старт EV.

Думаю, будет разница.

В моем автомате, если Вы заметили, переменная state 4 бита.  в режиме макс. скорости квартус кодирует автомат (проверено раньше у себя) как one-hot, т.не. не 4 триггера, а все 16 скорее всего будет) - вот Вам и лишняя логика.

Возможно, если хорошо подумать, то можно уложиться в 3 бита (8 состояний, а не 9 нужных).

Попробуйте глянуть в отчетах - так ли он сгенерировал автомат, а потом убрать галку синтеза по скорости - что станет с ресурсами.

Разница в скорости - вероятно, логика разная в проектах.

 

Edited by Yuri124

Share this post


Link to post
Share on other sites
1 hour ago, zombi said:

Взял самый простой и самый медленный из cpld MAXII (EPM240T100C5)

Было бы еще интересно, если бы Вы задали временные ограничения по сигналу EV. Если он действительно появляется не с фронтом clk, а через 3/4 такта, как на временной диаграмме.

При частоте 266 МГц  он должен меньше чем за 1 нс успеть пройти 3 слоя логики (инвертор, И и ИЛИ - хотя тут я могу быть неправ, если всё это на одной LUT реализовано) и поступить на входы разрешения сдвига регистра так, чтобы вписаться во время tsu (setup time) 8 триггеров. Какие там у MAXII задержки  по даташиту? Вот тут может частота резко упасть.

https://www.intel.com/content/dam/www/programmable/us/en/pdfs/literature/hb/max2/max2_mii5v1.pdf стр 83 - если я правильно посчитал, то полторы наносекунды должен сигнал иметь времени. Т.е. период clk должен быть не менее 6 нс.

Частота будет 167 МГц.

Правда - если строго по Вашей временной диаграмме на предыдущей странице. Если же EV появляется в том же такте сразу же после фронта clk  - тогда как по отчету квартуса.

34 minutes ago, Yuri124 said:

Разница в скорости - вероятно, логика разная в проектах.

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

Edited by Yuri124

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.