Перейти к содержанию
    

Verilog. Объясните в чем неправ.

Пишу модуль SPI. Заткнулся в самом начале. Почему этот код

always @ (posedge spi_clk or posedge spi_recv) begin
    if (spi_recv) begin
        if (spi_clk) begin
            if (count >= 16) begin
                count = 0;
                spi_new_data = 1;
            end else begin
                count = count + 1;
                spi_new_data = 0;
            end
        end else begin
            count = 0;
        end    
    end else begin
        count = 0;
    end
end

выдает такую диаграмму ?

post-16792-1215501027_thumb.jpg

 

Такой код работает нормально

always @ ( posedge spi_clk) begin 
    if (spi_recv) begin
        if (count > 15) begin
            count = 0;
            spi_new_data = 1;
        end else begin
            count = count + 1;
            spi_new_data = 0;
        end 
    end else begin
        count = 0;
    end        
end

post-16792-1215501039_thumb.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пишу модуль SPI. Заткнулся в самом начале. Почему этот код

always @ (posedge spi_clk or posedge spi_recv) begin
    if (spi_recv) begin
        if (spi_clk) begin
            if (count >= 16) begin
                count = 0;
                spi_new_data = 1;
            end else begin
                count = count + 1;
                spi_new_data = 0;
            end
        end else begin
            count = 0;
        end    
    end else begin
        count = 0;
    end
end

выдает такую диаграмму ?

Видимо потому, что posedge spi_recv в списке чуствительности блока always лишний, или if (spi_clk) лишний. Сначала объясните, что вы пытались написать :05:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Видимо потому, что posedge spi_recv в списке чуствительности блока always лишний, или if (spi_clk) лишний. Сначала объясните, что вы пытались написать :05:

 

Извините, не указал

always @ (CS) begin
    if (CS) begin
        spi_recv = 0;
    end else begin
        spi_recv = 1;
    end
end

 

Я пытался написать счетчик (до 16 со сбросом) принятых/отправленных бит, обнуляющийся при появлении сигнала CS и икрементирующийся по нарастающему фронту сигнала spi_clk.

Изменено пользователем Hz!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я пытался написать счетчик (до 16 со сбросом) ....

Ну а для начала посмотрели бы шаблоны, прежде чем писать. И там все это расписано до умопомрачения.

Шаблоны есть и в моделсиме, и в квартусе и в Исе, бери-не-хочу....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну а для начала посмотрели бы шаблоны, прежде чем писать. И там все это расписано до умопомрачения.

Шаблоны есть и в моделсиме, и в квартусе и в Исе, бери-не-хочу....

Уточню вопрос:

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Уточню вопрос:

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

 

хмм,

        if (spi_clk) begin
            if (count >= 16) begin
                count = 0;
                spi_new_data = 1;
            end else begin
                count = count + 1;
                spi_new_data = 0;
            end
        end else begin
            count = 0; // странные пчелы, наверное делают неправильный мед. 
        end

 

1. Как я понял вы используете альтеровский симулятор и код после синтеза и разводки. В этом случае нужно смотреть как синтезатор переварил то что вы у него попросили. Судя по коду возможно что у ква немного сорвало башню. Вроде просят синхронную логику с асинхронным сбросом, а в коде что то вообще странное.

 

2. По вейвформам видно что сильно колбасит счетчик. Это может быть из за иголок на на его входе тактовой частоты, из вашего объяснения не ясно как он формируется + логика счетчика странная.

 

Удачи !!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Уточню вопрос:

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

 

А бог его знает. Вы не используете внутреннюю системную частоту.

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

Плюс не полноценное поведенческое описание

end else begin

count = 0;

end

spi_new_data не описан. Синтезатор его по своему усмотрению наверно в lach превратит.

///

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

count <= count + 1'b1; Он как раз то, о чем Вы думаете.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Уточню вопрос:

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

Уточняю ответ. Если хотите, можете приобрести в КиТ (kit-e.ru) диск с русским описанием Верилога.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

При описании синхронных схем всегда следует использовать non-blocking assignment ( <= ).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

При описании синхронных схем всегда следует использовать non-blocking assignment ( <= ).

 

Отнюдь. Наглядный пример - перевод из двоичного в двоично-десятичный.

Попробуйте также лаконично с оператором <=

 

module bin2bcd

(

input clk,

input [12:0] bin,

output reg [15:0] bcd,

output reg enable_rd_bcd

);

 

reg [3:0] ct_bit;

reg [12:0] bin_rg;

reg [15:0] bcd_rg;

 

function [3:0] correct ;

input [3:0] decade;

begin

correct = (decade > 4) ? (decade + 4'd3) : decade;

end

endfunction

 

always @ (posedge clk)

begin

enable_rd_bcd = (ct_bit == 4'd0);

if (ct_bit == 4'd0) begin

bcd = bcd_rg;

bcd_rg = 16'd0;

bin_rg = bin;

ct_bit = 4'd13; end

else begin

bcd_rg[3:0] = correct(bcd_rg[3:0]);

bcd_rg[7:4] = correct(bcd_rg[7:4]);

bcd_rg[11:8] = correct(bcd_rg[11:8]);

bcd_rg[15:12] = correct(bcd_rg[15:12]);

bcd_rg = {bcd_rg[14:0], bin_rg[12]};

bin_rg = (bin_rg << 1);

ct_bit = ct_bit - 1'b1; end

end

 

endmodule

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Попробуйте также лаконично с оператором <=

 

не совсем понял ваше предложение, но вот мой вариант :)

 

/*

  logic          bin2bcd__clk         ;
  logic [11 : 0] bin2bcd__bin         ;
  logic [15 : 0] bin2bcd__bcd         ;
  logic          bin2bcd__enable_rd_bcd;


  bin2bcd
  bin2bcd
  (
    .clk           ( bin2bcd__clk           ) ,
    .bin           ( bin2bcd__bin           ) ,
    .bcd           ( bin2bcd__bcd           ) ,
    .enable_rd_bcd ( bin2bcd__enable_rd_bcd )
  );


  assign bin2bcd__clk           = '0;
  assign bin2bcd__bin           = '0;


*/



module bin2bcd
(
  clk           ,
  bin           ,
  bcd           ,
  enable_rd_bcd
);

  //------------------------------------------------------------------------------------------------------
  //
  //------------------------------------------------------------------------------------------------------

  input  logic          clk         ;
  input  logic [12 : 0] bin         ;
  output logic [15 : 0] bcd         ;
  output logic          enable_rd_bcd;

  //------------------------------------------------------------------------------------------------------
  //
  //------------------------------------------------------------------------------------------------------
  typedef logic [15:0] bcd_t;
  typedef logic [12:0] bin_t;
  typedef logic  [3:0] dec_t;

  dec_t ct_bit;
  bin_t bin_rg;
  bcd_t bcd_rg;

  //------------------------------------------------------------------------------------------------------
  //
  //------------------------------------------------------------------------------------------------------

  initial ct_bit = '0;

  always_ff @ (posedge clk) begin
    enable_rd_bcd <= (ct_bit == 0);
    //
    if (ct_bit == 0) begin
      bcd     <= bcd_rg;
      bcd_rg  <= '0;
      bin_rg  <= bin;
      ct_bit  <= 4'd13;
    end
    else begin
      bcd_rg  <= correct(bcd_rg, bin_rg[12]);
      bin_rg  <= (bin_rg << 1);
      ct_bit  <= ct_bit - 1'b1;
    end
  end

  function automatic dec_t correct_decade ( input dec_t decade);
    correct_decade = (decade > 4) ? (decade + 4'd3) : decade;
  endfunction

  function automatic bcd_t correct (input bcd_t data, input bit bitdata);
    int i;
  begin
    for (i = 0; i < 4; i++)
      correct [4*i +: 4] = correct_decade(data[4*i +: 4]);
    correct = (correct << 1) | bitdata;
  end
  endfunction

endmodule

 

за компактностью не гнался, гнался за простотой описания. синтезировал в ква, симулил в квесте с вашим модулем бьется один в один.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...