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

ModelSim вредина!?

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

 

Есть проект на который мигрирует с древнего Verilog на SV в котором выборка регистров на чтение сделана таким вот образом:

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

 

function rd_hit(input [15:0] raddr);
    rd_hit= rd_en                          &&
    (base_addr[4 +: 8]==rd_addr[4 +: 8])   &&
    (raddr[4 +: 4]       ==rd_addr[0 +: 4]);
endfunction
function [1+CORE_DATA_WIDTH-1:0] rd_bus(input [31:0] rdata, [15:0] raddr );
    if (rd_hit(raddr))
        rd_bus=(1<<CORE_DATA_WIDTH) | (rdata<<(raddr[3:2]*32));
    else
        rd_bus={CORE_DATA_WIDTH+1{1'b0}};
endfunction

Используется это так

localparam CH_CAP_REG     = 16'h0_0_00; //RO
localparam CH_CTRL_RW_REG = 16'h0_0_04; //RW
localparam CH_SOME_REG    = 16'h0_0_44; //RW

logic                       rd_data_vld_c;
logic [CORE_DATA_WIDTH-1:0] rd_data_c;
always @(*) begin
    {rd_data_vld_c,rd_data_c}=
        rd_bus(dma_cap, CH_CAP_REG)         |
        rd_bus(dma_ctrl, CH_CTRL_RW_REG)    |
        ....
        rd_bus(dma_some, CH_SOME_REG);
end

always @(posedge clk) begin
    rd_data <= rd_data_vld_c ? rd_data_c : {CORE_DATA_WIDTH{1'b0}};
end

При синтезе все это синтезируется нормально и никаких проблем не возникает а вот при симуляции в ModelSim (win64 v10.4с) always @(*) не работает корректно - такое впечатление что всегда работает только последняя линия - rd_bus(dma_some, CH_SOME_REG);

Если заменить на always_comb - все работает так как и предполагалось.

 

Даже не знаю что и думать

 

Удачи! Rob.

 

 

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


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

function rd_hit(input [15:0] raddr);
    rd_hit= rd_en                          &&
    (base_addr[4 +: 8]==rd_addr[4 +: 8])   &&
    (raddr[4 +: 4]       ==rd_addr[0 +: 4]);
endfunction

что-то у вас тут много всякого, что ни как вход, ни как-то ещё не объявлено?

rd_en

base_addr

rd_addr

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


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

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

что-то у вас тут много всякого, что ни как вход, ни как-то ещё не объявлено?

Зоркий глаз!

Это для экономии места на форуме rd_en и rd_addr это разрешение для чтения и адрес регистра для чтения соответственно, base_addr - это базовй адрес (фактически константа) для соответствующего канала.

input                                   rd_en;
input   [REG_ADDR_WIDTH-1:0]            rd_addr;
input   [REG_ADDR_WIDTH-1:0]            base_addr;

 

Удачи! Rob.

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


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

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

 

rd_hit=rd_en или rd_hit==rd_en?

...
rd_hit = rd_en  &&  (base_addr[4 +: 8]==rd_addr[4 +: 8])  &&  (raddr[4 +: 4]==rd_addr[0 +: 4]);
...

 

Удачи! Rob.

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


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

я то понял вопрос был в том что Вы действительно хотите присвоить или все же сравнить? :)

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


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

я то понял вопрос был в том что Вы действительно хотите присвоить или все же сравнить? :)

Конечно присвоить - это же функция.

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


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

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

 

Есть проект на который мигрирует с древнего Verilog на SV в котором выборка регистров на чтение сделана таким вот образом:

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

 

function rd_hit(input [15:0] raddr);
    rd_hit= rd_en                          &&
    (base_addr[4 +: 8]==rd_addr[4 +: 8])   &&
    (raddr[4 +: 4]       ==rd_addr[0 +: 4]);
endfunction
function [1+CORE_DATA_WIDTH-1:0] rd_bus(input [31:0] rdata, [15:0] raddr );
    if (rd_hit(raddr))
        rd_bus=(1<<CORE_DATA_WIDTH) | (rdata<<(raddr[3:2]*32));
    else
        rd_bus={CORE_DATA_WIDTH+1{1'b0}};
endfunction

Используется это так

localparam CH_CAP_REG     = 16'h0_0_00; //RO
localparam CH_CTRL_RW_REG = 16'h0_0_04; //RW
localparam CH_SOME_REG    = 16'h0_0_44; //RW

logic                       rd_data_vld_c;
logic [CORE_DATA_WIDTH-1:0] rd_data_c;
always @(*) begin
    {rd_data_vld_c,rd_data_c}=
        rd_bus(dma_cap, CH_CAP_REG)         |
        rd_bus(dma_ctrl, CH_CTRL_RW_REG)    |
        ....
        rd_bus(dma_some, CH_SOME_REG);
end

always @(posedge clk) begin
    rd_data <= rd_data_vld_c ? rd_data_c : {CORE_DATA_WIDTH{1'b0}};
end

При синтезе все это синтезируется нормально и никаких проблем не возникает а вот при симуляции в ModelSim (win64 v10.4с) always @(*) не работает корректно - такое впечатление что всегда работает только последняя линия - rd_bus(dma_some, CH_SOME_REG);

Если заменить на always_comb - все работает так как и предполагалось.

 

Даже не знаю что и думать

 

Удачи! Rob.

 

Попробуй вместо {rd_data_vld_c,rd_data_c}=

{rd_data_vld_c,rd_data_c} <=

 

может моделсим сожрет

 

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

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


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

Все по стандарту. @(*) не видит глобальные, для функций сигналы. В отличие от always_comb. Именно по этому его и ввели в стандарт

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


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

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

Все по стандарту. @(*) не видит глобальные, для функций сигналы. В отличие от always_comb. Именно по этому его и ввели в стандарт

Теперь понятно, спасибо. Судя по всему в новых версиях ModeSim гайки закручивает строго по стандарту - раньше ведь этот кусок симуляцию как то проходил.

 

глобалки и `define - зло.

Но эло обычно такое соблазнительное. В отличии от скучной праведности ;)

 

Удачи! Rob

 

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


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

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

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

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

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

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

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

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

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

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