Jump to content

    
Sign in to follow this  
RobFPGA

ModelSim вредина!?

Recommended Posts

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

 

Есть проект на который мигрирует с древнего 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.

 

 

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

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

Зоркий глаз!

Это для экономии места на форуме 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.

Share this post


Link to post
Share on other sites
Приветствую!

 

Есть проект на который мигрирует с древнего 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} <=

 

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

 

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

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

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

 

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

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

 

Удачи! Rob

 

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.

Sign in to follow this