Jump to content

    

Подключение SV модуля с многомерными портами в VHDL

Коллеги, нужна ваша помощь.

Никак не пойму где грабли.

Проблема следующая:

Подключаю SV модуль с многомерными портами в VHDL.

При моделировании в ModelSim вижу, что в SV модуль данные заходят, но в перевернутом виде. Младший бит вместо старшего. Байты также идут в обратном порядке.

При этом если заменить многомерный порт на одномерный, данные передаются корректно.

И вторая проблема.

Если объявить выходной многомерный порт как output reg, вместо обычного output, то ModelSim выдает ошибку.

Share this post


Link to post
Share on other sites

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

Ох, не вовремя вы! Вечер,  сил и манны на телепатию не осталось  - ну хоть какой-нибудь набросок вашего кода  и  капельку лога с ошибкой помогут сообразить что у вас не так.  Ну а иначе ждите до утра :smile:

Удачи! Rob.

Share this post


Link to post
Share on other sites
47 минут назад, BSACPLD сказал:

При моделировании в ModelSim вижу, что в SV модуль данные заходят, но в перевернутом виде. Младший бит вместо старшего. Байты также идут в обратном порядке. 

Видимо так подключили  в  VHDL модуле.

Если объявить выходной

 многомерный порт как output reg, вместо обычного output, то ModelSim выдает ошибку. 

Объявить где?

 

Edited by wolfman

Share this post


Link to post
Share on other sites

ну а оно downto в VHDL или to?

ну и как упаковывает SV в массив биты (хотя если и внутри самой младшей размерности наоборот, то это вряд ли) - то есть порядок квадратных скобочек правильный?

Share this post


Link to post
Share on other sites

SV включается в VHDL.

В SV файле обычная APB шина.

// APB slave
input PCLK,
input PRESETn,
input [APB_ADDR_WIDTH-1:0] PADDR,
input PSELx,
input PENABLE,
input PWRITE,
input [APB_DATA_WIDTH/8-1:0][7:0] PWDATA,
output reg PREADY,
output reg [APB_DATA_WIDTH/8-1:0][7:0] PRDATA,
output PSLVERR,

Со стороны VHDL.

PRESETn : in  std_logic;
PADDR   : in  std_logic_vector(APB_ADDR_WIDTH - 1 downto 0);
PWRITE  : in  std_logic;
PREADY  : out std_logic;
PWDATA  : in  std_logic_vector(APB_DATA_WIDTH - 1 downto 0);
PRDATA  : out std_logic_vector(APB_DATA_WIDTH - 1 downto 0);
PSEL    : in  std_logic;
PENABLE : in  std_logic;
PSLVERR : out std_logic;

Т.е. просто проброс на уровень выше.

17 minutes ago, wolfman said:

Объявить где?

В SV модуле.

Так вот если в SV написать так:

// APB slave
input PCLK,
input PRESETn,
input [APB_ADDR_WIDTH-1:0] PADDR,
input PSELx,
input PENABLE,
input PWRITE,
input [APB_DATA_WIDTH-1:0] PWDATA,
output PREADY,
output [APB_DATA_WIDTH-1:0] PRDATA,
output PSLVERR,

То все работает правильно.

Если как в начале поста, то байт/бит реверс.

Share this post


Link to post
Share on other sites

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

3 hours ago, BSACPLD said:

При моделировании в ModelSim вижу, что в SV модуль данные заходят, но в перевернутом виде. Младший бит вместо старшего. Байты также идут в обратном порядке.

Кажется мне что переворачивается оно где-то у вас в другом месте -  во всяком случае у меня в сляпанном на  скорую руку примерчике все правильно передается.  

Что касается     output reg [..][..] dou, то тут да - засада присутствует  :scratch_one-s_head:Modelsim ругается 

Error: (vsim-8428) Cannot connect a VHDL array signal to Verilog multi dimensional array port

Если объявлять output wire [..][..] dou  то все пучком коннектится.  Причем такая дискриминация по полу типу порта  похоже только для packed массивов - для unpacked варианта порта  output reg [..] dou [..], отлично коннектится к 2d массиву в vhdl. 

Думаю что это глюк из разряда особенностей mixsed simulation Modelsim,  как и например глюк с попыткой присвоить значение для generic типа std_logic из SV модуля.    

Удачи! Rob.

tst.thumb.png.dfb88668fe9747a5d7f65d1bd59c95d3.png

Share this post


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

Кажется мне что переворачивается оно где-то у вас в другом месте -  во всяком случае у меня в сляпанном на  скорую руку примерчике все правильно передается.

В том то и прикол, что ставлю одномерный массив в SV модуле - передается корректно, двумерный - реверс.

Может ли порядок присвоения бит зависеть от каких-либо настроек ModelSim/языковых конструкций в VHDL?

Там большой и сложный блок который писали еще до меня, так что я пока слабо представляю, что там наворочено.

 

P.S.

Хотя конечно может это и глюк ModelSim. Я уже замечал, что 10.5d некорректно моделировал одну ошибку. Т.е. ошибка была, а ModelSim показывал, что все хорошо.

Причем и QuestaSim 10.6c тоже. А вот 10.7c и 2019.2 уже нормально отрабатывали.

P.P.S.

Еще один интересный прикол.

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

Share this post


Link to post
Share on other sites

Хм, что-то я не вижу многомерного массива в VHDL, так и задумано?

Share this post


Link to post
Share on other sites
6 часов назад, BSACPLD сказал:

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

Возможно, дефолтовые настройки разные.

Share this post


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

Хм, что-то я не вижу многомерного массива в VHDL, так и задумано?

Да.

Share this post


Link to post
Share on other sites
7 minutes ago, BSACPLD said:

Да.

А Вы попробуйте сделать многомерный массив на VHDL и посмотрите, действительно ли данные не в том порядке? Иначе это можно гадать до бесконечности.

type apb_t is array [APB_DATA_WIDTH/8-1:0] of std_logic_vector [7:0]

И да, VHDL не любит, когда играются с порядком. Он проще работает без "волшебных" конструкций (типа одномерный массив в многомерный, реверс бит и т.д.). Хотя много ещё зависит от среды проектирования.

 

12 hours ago, BSACPLD said:

Если объявить выходной многомерный порт как output reg, вместо обычного output, то ModelSim выдает ошибку

Тут ещё есть нюанс в присвоении. Регистры на выход лучше присваивать в always_ff структуре (не обязательно), в то время wire требуют assign или always_comb.

Share this post


Link to post
Share on other sites
1 минуту назад, Nick_K сказал:

А Вы попробуйте сделать многомерный массив на VHDL и посмотрите, действительно ли данные не в том порядке? Иначе это можно гадать до бесконечности. 

type apb_t is array [APB_DATA_WIDTH/8-1:0] of std_logic_vector [7:0]

 

В таком случае скорее всего будет работать правильно, как и с одномерным массивом.

Share this post


Link to post
Share on other sites

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

9 hours ago, BSACPLD said:

В том то и прикол, что ставлю одномерный массив в SV модуле - передается корректно, двумерный - реверс.

Вот мои подопытные

Spoiler

`default_nettype none
module ss_sv #(parameter D_WH = 64) (
  input  wire                    clk,
  input  wire                    rst,
  input  wire  [D_WH/8-1:0][7:0] din,
  output wire  [D_WH/8-1:0][7:0] dou
  // output logic [       7:0]      dou [D_WH  /8-1:0]
);

logic [D_WH/8-1:0][7:0] din_r;

generate
  for (genvar gi=0; gi<D_WH/8; ++gi) begin
    assign dou[gi] = din_r[gi];
  end
endgenerate

always_ff @(posedge clk) begin
  din_r <= rst ? '0 : din;
end

endmodule
`default_nettype wire


library ieee;
use ieee.std_logic_1164.all;

entity ss_vhd is
  generic(
    D_WH : integer := 64
  );
  port(
    clk  : IN     std_logic;
    rst  : IN     std_logic;
    din  : IN     std_logic_vector( D_WH-1 downto 0);
    dou  : OUT    std_logic_vector( D_WH-1 downto 0)
  );
end ss_vhd ;

architecture behav of ss_vhd is
type ar_u8_t is array (natural range<>) of std_logic_vector(7 downto 0);

component ss_sv
  generic (
    D_WH : integer := 64
  );
  port (
    clk  : in  std_logic;
    rst  : in  std_logic;
    din  : in  std_logic_vector (D_WH-1 downto 0);
    dou  : out std_logic_vector (D_WH-1 downto 0)
    --dou  : out ar_u8_t (D_WH/8-1 downto 0)
  );
end component;

signal dou_o : ar_u8_t (D_WH/8-1 downto 0);

begin

iss_sv : ss_sv
  generic map (
    D_WH => D_WH
  )
  port map (
    clk  => clk,
    rst  => rst,
    din  => din,
    dou  => dou
--    dou  => dou_o
  );

--map_io : for gi in 0 to D_WH/8-1 generate
--  dou (gi*8+7 downto gi*8 ) <= dou_o(gi);
--end generate;

end behav;
    

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity ss_tb IS
  generic(
    D_WH : integer := 32
  );
end ss_tb ;

architecture behav of ss_tb is

constant CLK_T : time := 10 ns;
constant RST_T : time := 20 ns;

component ss_vhd
  generic (
    D_WH : integer := 64
  );
  port (
    clk  : in  std_logic;
    rst  : in  std_logic;
    din  : in  std_logic_vector (D_WH-1 downto 0);
    dou  : out std_logic_vector (D_WH-1 downto 0)
  );
end component;

signal clk  : std_logic ;
signal rst  : std_logic ;
signal din  : std_logic_vector (D_WH-1 downto 0);
signal dou  : std_logic_vector (D_WH-1 downto 0);

begin

iss_vhd : ss_vhd
  generic map (
    D_WH => D_WH
  )
  port map (
    clk  => clk,
    rst  => rst,
    din  => din,
    dou  => dou
  );

clk_proc : process
begin
  clk <= '0';
  wait for CLK_T/2;
  clk <= '1';
  wait for CLK_T/2;
end process clk_proc;

rst_proc : process
begin
  rst <= '1';
  wait for RST_T;
  rst <= '0';
  wait for 100 us;
end process rst_proc;

sim_proc : process (rst, clk)
begin
  if (rst = '1') then
    din  <= (others =>'0');
  elsif (rising_edge(clk)) then
    if (unsigned(din) = 0) then
      din <= din(D_WH-2 downto 0) & '1';
    else
      din <= din(D_WH-2 downto 0) & '0';
    end if;
  end if;
end process sim_proc;

end behav;

 

Поведение и порядок бит/байт одинаковое  как для варианта output wire [D_WH/8-1:0][7:0] dou  так и для output logic|wire [7:0] dou [D_WH  /8-1:0].

Вариант с output reg|logic [D_WH/8-1:0][7:0] dou падает с ошибкой (vsim-8428).  И больше ни каких приколов. :unknw:
 

Удачи! Rob.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this