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

FSM встаёт на ровном месте: либо я дурак, либо так оно и есть...

Всем добра.
Не могу понять, что не так ...
Модуль проекта
 

`include "defines.inc"

module ozu2dwb (                        // write with busy processing

    // globals
    input  logic rstn,                   // reset - active low	
    input  logic clk64MHz,               // global clock 64 MHz
    
    // locals from internal    
    input  logic  [`CH_SH_RNG] channel,  // channel to write
    input  logic  [`RG_RNG] register,    // register to write 
                                        // 0 - receive zone, 
                                        // 1 - transmit zone, 
                                        // 2 - control register, 
                                        // 3 - error register, 
                                        // 4 - state register
                                        
    input  logic [`LOC_ADDR_WDTH_RNG]   addr_loc,
    input  logic [`OZU2D_DATA_WDTH_RNG] data_loc,
    input  logic write,
    output logic is_ozu2d_written, // write done
    
    // global to ozu2d    
    output logic [`OZU2D_ADDR_WDTH_RNG] addr2ozu2d,
    output logic  [`OZU2D_DATA_WDTH_RNG] data2ozu2d,
    input  logic busyn, // busy input active low
    output logic cen2ozu2d,
    output logic oen2ozu2d,
    output logic rwn2ozu2d,
    
    // from defines.inc
    // `define STATE_OZU2DWB_DIM 2
    // `define STATE_OZU2DWB_RNG `STATE_OZU2DWB_DIM-1:0
    output logic [`STATE_OZU2DWB_RNG] state_out
    
);

    enum logic [`STATE_OZU2DWB_RNG] {
        ST_IDLE         = `STATE_OZU2DWB_DIM'd0, 
        ST_WRITE        = `STATE_OZU2DWB_DIM'd1, 
        ST_CHK_BUSY     = `STATE_OZU2DWB_DIM'd2,
        ST_DONE         = `STATE_OZU2DWB_DIM'd3
    } state;
    assign state_out = state;	

    logic write_latched;

    // hold data at ozu2d data bus for the whole write_latched duration
    assign data2ozu2d = write_latched ? data_loc : 'z;
                  
    logic write_low;
	assign write_low = state == ST_WRITE || state == ST_CHK_BUSY;
    
    logic stop;
	assign stop = state == ST_DONE;

    always_ff @(posedge clk64MHz)
        if(!rstn) begin
            is_ozu2d_written  <= 1'b0;
            write_latched     <= 1'b0;
            rwn2ozu2d         <= 1'b1;
            cen2ozu2d         <= 1'b0; // 1b'1;
            oen2ozu2d         <= 1'b1;
            state             <= ST_IDLE;
        end
        else begin
            write_latched     <= write ? 1'b1 : stop ? 1'b0 : write_latched;
            is_ozu2d_written  <= stop;
            rwn2ozu2d         <= !write_low;
            // cen2ozu2d      <= !write_low;
            case (state)
                ST_IDLE:      state <= write ? ST_WRITE : ST_IDLE;
                ST_WRITE:     state <= ST_CHK_BUSY;  
                ST_CHK_BUSY:  state <= busyn ? ST_DONE : ST_CHK_BUSY;
                ST_DONE:      state <= ST_IDLE; 
            endcase
        end  
      
    resolve_address resolve_address_inst(
        .*, 
        .addr_ozu2d(addr2ozu2d)
    ); 
 		
endmodule : ozu2dwb

Будучи выведен своими сигналами на встроенный в осциллоскоп логический анализатор,
показывает (редко, но метко, после чего стопорит весь проект намертво) следующую картину

image.thumb.png.8883e4f638f05813b011bd0a93ec325d.png

D7:D6 = state;
D5    = busyn;             
D4    = clk64MHz;         
D3    = rwn2ozu2d; 
D2    = не важно      
D1    = не важно

а внизу показана расшифровка шины D7:D6 = state.

Т.е. суть в том, что в состоянии ST_DONE = `STATE_OZU2DWB_DIM'd3 из которого FSM должна безусловно переходить в ST_IDLE = `STATE_OZU2DWB_DIM'd0, она встаёт как вкопанная.
Я подозреваю, что дело во мне, но не могу понять (с) В августе 44-го. Просьба помочь.

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


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

write и busyn внешние сигналы? 

ЗЫ. Заканчивайте макросы вот таким способом использовать, вам самим глаз не режет подобное описание, да к тому же еще и бесполезное. 

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


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

Внешние.
ЗЫ. Глаз ничего не режет, а должно? Насчёт бесполезности тоже прошу пояснить.

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


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

2 minutes ago, MaratZuev said:

Внешние.

синхронный автомат, асинхронные сигналы... классика 

2 minutes ago, MaratZuev said:

ЗЫ. Глаз ничего не режет, а должно? Насчёт бесполезности тоже прошу пояснить.

Куча макросов задающих разрядность векторов, совершенно лишние макросы в разрядностях (этож верилог). При этом все это на глобальном уровне иерархии, без проверки типов. А самое забавное, что все это в SV, в документах к которому настоятельно не рекомендуют задавать константы макросами. 

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


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

6 minutes ago, des00 said:

синхронный автомат, асинхронные сигналы... классика 

ну один из них синхронный, т.к. берётся из того же проекта, а вот busy - в действительности был синхронизирован классической схемой ранее, но, почему-то, от неё отказался. Рекомендуете вернуть обратно и доложиться о результатах?

9 minutes ago, des00 said:

Куча макросов задающих разрядность векторов, совершенно лишние макросы в разрядностях (этож верилог).

Да, это бездумный перенос из верилога. Спасибо, что ткнули носом: как разберусь с этим пердимоноклем, займусь TFM по предмету.

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


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

Переработал. Прошу критиковать

module ozu2dwb (                  // write with busy processing

    // globals
    input  logic rstn,            // reset - active low	
    input  logic clk64MHz,        // global clock 64 MHz
    
    // locals from internal    
    input  logic  [1:0] channel , // channel to write
    input  logic  [2:0] register, // register to write 
                                  // 0 - receive zone, 
                                  // 1 - transmit zone, 
                                  // 2 - control register, 
                                  // 3 - error register, 
                                  // 4 - state register
                                        
    input  logic [7:0]  addr_loc,
    input  logic [31:0] data_loc,
    input  logic write,
    output logic is_ozu2d_written, // write done
    
    // global to ozu2d    
    output logic [12:0] addr2ozu2d,
    output logic [31:0] data2ozu2d,
    
    input  logic busyn,            // busy input active low
    
    output logic cen2ozu2d,
    output logic oen2ozu2d,
    output logic rwn2ozu2d
    
);
    
    logic [1:0] busyn_mst_reg;
    always_ff @(posedge clk64MHz)
        busyn_mst_reg <= !rstn ? '0 : {busyn_mst_reg[0], busyn};

    logic busyn_mst;
    assign busyn_mst = busyn_mst_reg[1];        

    enum logic [2:0] {
        IDLE     = 3'd0, 
        START    = 3'd1,
        WAIT1    = 3'd2,
        WAIT2    = 3'd3,        
        CHK_BUSY = 3'd4,
        DONE     = 3'd5
    } state;

    logic  write_latched;
    assign data2ozu2d = write_latched ? data_loc : 'z;
                  
    logic  write_low;
	assign write_low = state == START || 
                       state == WAIT1 ||
                       state == WAIT2 ||
                       state == CHK_BUSY;
                       
    logic  stop;
	assign stop = state == DONE;                       

    always_ff @(posedge clk64MHz)
        if(!rstn) begin
            is_ozu2d_written  <= 1'b0;
            write_latched     <= 1'b0;
            rwn2ozu2d         <= 1'b1;
            oen2ozu2d         <= 1'b1;
            state             <= IDLE;
        end
        else begin
            write_latched     <= write ? 1'b1 : 
                                 stop  ? 1'b0 : 
                                 write_latched;
            is_ozu2d_written  <= stop;
            rwn2ozu2d         <= !write_low;
            // cen2ozu2d      <= !write_low;
            case (state)
                IDLE:      state <= write ? START : IDLE;
                START:     state <= WAIT1;  
                WAIT1:     state <= WAIT2;                
                WAIT2:     state <= CHK_BUSY;  
                CHK_BUSY:  state <= busyn_mst ? DONE : CHK_BUSY;
                DONE:      state <= IDLE; 
            endcase
        end  
      
    resolve_address resolve_address_inst(
        .*, 
        .addr_ozu2d(addr2ozu2d)
    ); 
 		
endmodule : ozu2dwb

Времянка выглядит так:

image.thumb.png.5e4491856fb15b3a5e13a577470af675.png

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


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

6 hours ago, MaratZuev said:

Переработал. Прошу критиковать

Код как код, как по мне "грязноватый" конечно, но может у вас такие coding rules.

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


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

5 hours ago, des00 said:

может у вас такие coding rules.

Были бы coding rules, я был бы счастливее, а пока приходится искать и подглядывать чужое.
Вы бы не могли, так сказать, не безвозмездно, конечно, дать взглянуть на Ваш код?
"Клянусь, я никому не скажу!" как сказал Воланд Берлиозу в сцене встречи на Патриарших из "Мастера и Маргариты" Михаила Афанасьевича Булгакова.

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


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

58 minutes ago, MaratZuev said:

Вы бы не могли, так сказать, не безвозмездно, конечно, дать взглянуть на Ваш код?

https://electronix.ru/forum/index.php?app=forums&module=forums&controller=topic&id=100684

выбирайте) более поздние ИМХО более правильные)

 

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


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

20 hours ago, MaratZuev said:

Т.е. суть в том, что в состоянии ST_DONE = `STATE_OZU2DWB_DIM'd3 из которого FSM должна безусловно переходить в ST_IDLE = `STATE_OZU2DWB_DIM'd0, она встаёт как вкопанная.
Я подозреваю, что дело во мне, но не могу понять (с) В августе 44-го. Просьба помочь.

Я бы на вашем месте добавил default: в case (state), потому что тип logic имеет 4 состояния и ваш case не описывает все возможные состояния state

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


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

16 часов назад, des00 сказал:

https://electronix.ru/forum/index.php?app=forums&module=forums&controller=topic&id=100684

выбирайте) более поздние ИМХО более правильные)

 

ldpc_3gpp из последнего на сегодняшний день поста

 

Относится к ранним или более поздним?

 

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


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

3 minutes ago, dxp said:

ldpc_3gpp из последнего на сегодняшний день поста

Относится к ранним или более поздним?

к поздним, 20ый год. тут у меня стиль уже устаканился. Просто удивился что теме 10 лет, 10 лет назад я еще экспирементировал)

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


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

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

 

Собственно, у меня был только один вопрос: если уже активно используется SV, то почему бы тогда не засунуть все определения заголовочных файлов в пакеты, которые импортировать в "шапке" модуля:

// header
package automatic defs;

localparam DATA_W = 8;
...
typedef logic [$clog2(DATA_W)-1:0] data_t;
...

endpackage : defs

// source  
module automatic slon_m import defs::*;
(
    input logic clk,
    ...
    input data_t data,
    ...
);

...
  
endmodule : slon_m

Ответ, похоже, вы уже дали - устоявшийся стиль. Стиль - штука важная и тонкая, формируется годами, меняется тяжело, нужны серьёзные основания для этого. Вторая причина может быть в возможно худшей переносимости SV варианта, хотя современные FPGA синтезаторы такое уже вроде умеют все.

 

Ещё обратил внимание, что в некоторых классах у функций-членов указан класс памяти automatic. Имхо, это лишнее - в классах функции-члены по умолчанию имеют автоматический класс памяти. Ну, для модулей и пакетов уже приучился сразу писать в определении один раз, чтобы в каждой функции не указывать это явно.

 

И вот тут ещё:

    function automatic void init_SNR (real SNR = 0, Ps = 1, int seed = 0);
      this.EbNo   = 1000;
      this.seed   = seed;
      this.SNR    = SNR;
      this.sigma  = get_sigma(SNR, Ps);
    endfunction

Явное указание this для членов класса тут зачем используется? Насколько помню, для членов класса this применяется неявно само по себе.

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


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

31 minutes ago, dxp said:

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

 

Собственно, у меня был только один вопрос: если уже активно используется SV, то почему бы тогда не засунуть все определения заголовочных файлов в пакеты, которые импортировать в "шапке" модуля:

Экспирементировал с пакетами, не смог с ними ужиться. С одной стороны штука удобная, пробовал, но как только в проекте появляется больше одного инстанса одного IP с разными параметрами ядра, то возникает проблема. Да, ее можно обойти, но такое решение не всегда красиво и мне не нравится.

Использование старой техники на основе локальных include файлов, с описанием типов позволяет обеспечить простую сквозную передачу параметров по всей иерархии и использовать user define типы. Глобальные include так не могут, макросы тоже. Вот если бы в пакеты можно было передать параметры, а потом переопределенный пакет передать в модуль тогда было бы удобно. Но в стандарте я не нашел такой возможности, хотя может быть плохо искал.

Quote

Ответ, похоже, вы уже дали - устоявшийся стиль. Стиль - штука важная и тонкая, формируется годами, меняется тяжело, нужны серьёзные основания для этого. Вторая причина может быть в возможно худшей переносимости SV варианта, хотя современные FPGA синтезаторы такое уже вроде умеют все.

Когда все начиналось, поддержка SV только вводилась, поэтому код писался так, чтобы можно было быстро заменить все на чистый верилог, при необходимости. Ну и слишком сильно за годы вьелось. Даже return не приучил себя использовать.

Quote

Ещё обратил внимание, что в некоторых классах у функций-членов указан класс памяти automatic. Имхо, это лишнее - в классах функции-члены по умолчанию имеют автоматический класс памяти. Ну, для модулей и пакетов уже приучился сразу писать в определении один раз, чтобы в каждой функции не указывать это явно.

Согласен, но скорее всего это забитые мной шаблоны сликедита или руки сами на автомате пишут. Стандарту не противоречит)

Quote

И вот тут ещё:


    function automatic void init_SNR (real SNR = 0, Ps = 1, int seed = 0);
      this.EbNo   = 1000;
      this.seed   = seed;
      this.SNR    = SNR;
      this.sigma  = get_sigma(SNR, Ps);
    endfunction

Явное указание this для членов класса тут зачем используется? Насколько помню, для членов класса this применяется неявно само по себе.

Это привычка самодокументирования, когда изучал VMM по книгам Janck Bergeron счел это разумным. А именно здесь SNR есть в параметрах функции и как локальная переменная. Остальные переменные определены таким способом для красоты)

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


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

Приветствую!

58 minutes ago, des00 said:

Экспирементировал с пакетами, не смог с ними ужиться. С одной стороны штука удобная, пробовал, но как только в проекте появляется больше одного инстанса одного IP с разными параметрами ядра, то возникает проблема. Да, ее можно обойти, но такое решение не всегда красиво и мне не нравится.

Эх...  сложности  с generic  программированием для синтеза в SV иногда портят  всю его красоту. :cray:
Помню тоже  был разочарован невозможностью параметризировать пакеты.  Статический  контент  в пакеты засовывать самое то, а вот параметры упс,  облом. В последнее  время правда можно делать этакие эрзац-пакеты через функции в параметризируемых интерфейсах  но  это все еще  сильно зависит от поддержки в синтезаторах. 

 

Удачи! Rob.

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


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

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

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

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

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

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

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

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

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

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