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

Можете дать подсказку как мне при моделировании в Modelsim'e вместо чисел выводить слова. Например:

У меня объявлена константа

CONSTANT CMD_ACTIVE         : STD_LOGIC_VECTOR(2 DOWNTO 0) := "011";

Которая в зависимости от условий работы схемы записывается в выходной регистр команд:

 SDRAM_CMD    <= CMD_ACTIVE

Очень хотелось бы при моделировании видеть то что находиться в регистре в виде слов, а не цифр.

Например состояния автомата при моделировании отображаются в виде слов.

Изменено пользователем Flip-fl0p

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


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

У Vivado от Xilinx очень удобный симулятор, конечно не Specman или System Verilog но приятно удивил. Модельсим хорош именно своим стабильным TCL скрипт мотором, жаль его не использовать в вашем случае, идеален для автоматизации.

Ну и вот как работать со сторонними для кода и даты :

http://surf-vhdl.com/write-to-file-in-vhdl...textio-library/

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


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

Неужели нельзя никак это реализовать ?

 

Сам отвечу на свой вопрос. Это можно сделать, добавив немного изврата:

Вместо констант составить пользовательский тип данных, как обычно делается при описании автоматов Мили\Мура.

Затем написать функцию преобразования типов. Курение мануалов, и гугла дало результат.

Вот пример(писал сам):

    TYPE COMMAND IS
    (
     NOP,            -- 00 на выходе будет
     PRECHARGE,-- 01 на выходе будет
     REFRESH     -- 10 на выходе будет
    );
    SIGNAL COMMAND_REG:COMMAND;
BEGIN
    COMMAND_REG <= PRECHARGE;
    OUTPUT_DATA   <= std_logic_VECTOR(to_unsigned(COMMAND'pos(COMMAND_REG), 2)); 
    -- На выходе команда PRECHARGE передастся в виде двоичного числа.
    -- По умолчанию первое описанное состояние кодируется нулем в двоичной системе
    -- Второе описанное состояние кодируется единицей  в двоичной системе и.т.д.
    -- При необходимости способ кодирования состояний можно изменить.

 

 

 

 

Интересное поведение Modelsim'a. По неясной мне причине, он игнорирует переназначение атрибутов кодирования сигналов состояния.

  TYPE COMMAND_SDRAM IS
    (
        CMD_LOADMODE,    --:= "000", 
        CMD_REFRESH    ,    --:= "001",
        CMD_PRECHARGE,    --:= "010",            
        CMD_ACTIVE ,            --:= "011",
        CMD_WRITE,        --:= "100",   
        CMD_READ,        --:= "101",
        CMD_NOP            --:= "110 А должно быть 111. Непонятно почему Modelsim делает по-своему.
    );   
    ATTRIBUTE ENUM_ENCODING : STRING;
    ATTRIBUTE ENUM_ENCODING OF COMMAND_SDRAM : TYPE IS "000 001 010 011 100 101 111";
    SIGNAL SDRAM_CMD :COMMAND_SDRAM:=CMD_NOP;  
    SIGNAL SDRAM_CMD_REG :STD_LOGIC_VECTOR(2 DOWNTO 0);     
BEGIN
--====ВЫДАЕМ КОМАНДЫ ПАМЯТИ======
SDRAM_CMD_REG<= std_logic_VECTOR(to_unsigned(COMMAND_SDRAM'pos(SDRAM_CMD), 3)); 
SDRAM_RAS_N  <= SDRAM_CMD_REG(2);
SDRAM_CAS_N  <= SDRAM_CMD_REG(1);
SDRAM_WREN_N <= SDRAM_CMD_REG(0);
--==============================

 

Интересно, как заставить его воспринять правильно код. Где-то видел, что надо хитрую TCL команду подать. Знать бы какую.... Для моделирования я добавляю "лишнюю" команду которую не использую. Он это "кушает", и работает правильно.....

    TYPE COMMAND_SDRAM IS
    (
        CMD_LOADMODE,    --:= "000", -- Режим загрузки данны в MODE REGISTER
        CMD_REFRESH    ,    --:= "001",
        CMD_PRECHARGE,    --:= "010",            
        CMD_ACTIVE ,    --    := "011",
        CMD_WRITE,        --:= "100",   
        CMD_READ,        --:= "101",
        ERROR,          -- Без этого сигнала 
        CMD_NOP            --:= "111"
    );   
    SIGNAL SDRAM_CMD :COMMAND_SDRAM:=CMD_NOP;  
    SIGNAL SDRAM_CMD_REG :STD_LOGIC_VECTOR(2 DOWNTO 0);   --COMMAND REGISTER

 

 

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


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

Сам отвечу на свой вопрос. Это можно сделать, добавив немного изврата:
Разумеется, всё надо делать руками. Нет никакой связи между состоянием регистра, и некоторой константой.

Интересное поведение Modelsim'a. По неясной мне причине, он игнорирует переназначение атрибутов кодирования сигналов состояния.
Ничего интересного. Все атрибуты предназначены для синтеза. Как симулятор представляет внутри себя перечислимый тип, это его внутреннее дело. Вас на данном этапе это волновать не должно. Возможно, волновать будет на этапе синтеза, поскольку там возможны варианты.

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


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

Очень хотелось бы при моделировании видеть то что находиться в регистре в виде слов, а не цифр.

Например состояния автомата при моделировании отображаются в виде слов.

 

Введите в описание автомата вывод на консоль или в файл названия состояния, времени моделирования и значения интересующих Вас регистров...

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


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

Разумеется, всё надо делать руками. Нет никакой связи между состоянием регистра, и некоторой константой.

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

Как раз таки в моем случае это важно поскольку команды SDR SDRAM представляют собой комбинации сигналов RAS, CAS, WE, которые я выдаю памяти. Например команда "бездействия" (NO OPERATION) представляет собой сочетание сигналов RAS = 1 CAS = 1 WE = 1. В моем случае Modelsim их "оптимизировал". И на моделировании я вижу "Оптимизированный" вариант в виде RAS = 1 CAS = 1 WE = 0. Естественно контроллер памяти работает некорректно.

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


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

В моем случае Modelsim их "оптимизировал"
Никто ничего не оптимизировал.

И на моделировании я вижу "Оптимизированный" вариант в виде RAS = 1 CAS = 1 WE = 0.
Ещё раз: никакой оптимизации тут нет в принципе. Вы видите то, что и должно быть в случае

SDRAM_CMD_REG<= std_logic_VECTOR(to_unsigned(COMMAND_SDRAM'pos(SDRAM_CMD), 3));

Откройте любую книгу по VHDL и прочтите описание атрибута 'pos.

Почитайте в стандарте описание enumeration type. Там всё предельно ясно написано.

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


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

Нашел способ как ещё проще сделать то, что я хочу(чтобы битовые вектора отображались в виде команд, которые мне нужны, а не в виде десятичных цифр, двоичных, шестнадцатиричных).

Например у меня есть 2 сигнала:

req_wr - сигнал запроса на чтение

req_rd - сигнал запроса на запись

Хотелось бы видеть на диаграммах их в виде команд:

NO_REQ      ( когда сигналы req_wr = 0, req_rd = 0) - значит нет запроса
WRITE_REQ ( когда сигналы req_wr = 1, req_rd = 0) - запрос на запись
READ_REQ   ( когда сигналы req_wr = 0, req_rd = 1) - запрос на чтение
READ_PRIOR_REQ ( когда сигналы req_wr = 1, req_rd = 1) - значит у нас запрос на чтение, поскольку у него больший приоритет.

 

Для этого можно воспользоваться TCL скриптом и назначить пользовательский radix.

Код буквально делает то-же что я написал. Единственное его условие, что он не может это сделать сигналами типа STD_LOGIC. А вот с STD_LOGIC_VECTOR все работает. Хотя если скомбинировать сигналы типа STD_LOGIC, то так-же будет работать. На картинке у меня сигналы STD_LOGIC скомбинированы.

 

Чтобы это сделать необходимо в консоле Modelsim'а написать следующее:

 

radix define radix_rd_req {
    "2'b00" "NO_REQ" -color "white",
    "2'b01" "READ_REQ" -color "white",
    "2'b10" "WRITE_REQ" -color "white",
    "2'b10" "READ_PRIOR_REQ" -color "white",
}

 

 

 

radix.png

 

 

 

 

И никаких "извращений" с текстом схемы делать не надо.

Изменено пользователем Flip-fl0p

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


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

Помогите разобраться. Очень странно работает моделирование в Modelsim'e.

Ситуация какая: я моделирую смешанные языки (verilog и VHDL), но поскольку бесплатная версия Modelsim'а накладывает ограничение на смешанное моделирование, я целевой файл ( в моем случае SDRAM контроллер) компилирую в Quartuse'e в виде выходных файлов verilog. И в Modelsim'e я работаю на Veriloge. В таком режиме мне доступна только временная симуляция.

Столкнулся с неприятной проблемой: по какой-то неизвестной мне причине обычный счетчик начинает неправильно считать.

Счётчик был объявлен так:

 

    SIGNAL INIT_CNT                : INTEGER   := 0;                                       -- Счётчик инициализации
BEGIN
...
...
    INIT_COUNTER:PROCESS
    (
        CLK
    )
    BEGIN
        IF RISING_EDGE(CLK) THEN
            IF (INIT_CNT < (TINIT+2*TRFC+TRP+3+1)) THEN
                INIT_CNT <= INIT_CNT+1;
            END IF;
        END IF;
    END PROCESS INIT_COUNTER;

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


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

Помогите разобраться. Очень странно работает моделирование в Modelsim'e.

Ситуация какая: я моделирую смешанные языки (Verilog - модель SDR SDRAM памяти, написанная производителем и VHDL контроллер этой памяти), но поскольку бесплатная версия Modelsim'а накладывает ограничение на смешанное моделирование, я целевой файл ( в моем случае SDRAM контроллер) компилирую в Quartuse'e в виде выходных файлов verilog. И в Modelsim'e я работаю на Veriloge. В таком режиме мне доступна только временная симуляция.

Столкнулся с неприятной проблемой: по какой-то неизвестной мне причине обычный счетчик начинает неправильно считать.

Счётчик был объявлен так:

 

    
ENTITY SDRAM_CONTROLLER IS
    GENERIC 
    (
        SDRAM_FREQUENCY    : INTEGER := 50 --MEMORY FREQUENCY IN MHZ
    );
....
....
....
     CONSTANT TINIT            : INTEGER :=    (100*SDRAM_FREQUENCY);        
     CONSTANT TRFC            : INTEGER :=    4;
     CONSTANT TRP            : INTEGER :=    ((SDRAM_FREQUENCY * 20)/1000);    
     SIGNAL INIT_CNT                : INTEGER   := 0;                                       -- Счётчик инициализации
BEGIN
...
...
    INIT_COUNTER:PROCESS
    (
        CLK
    )
    BEGIN
        IF RISING_EDGE(CLK) THEN
            IF (INIT_CNT < (TINIT+2*TRFC+TRP+3+1)) THEN
                INIT_CNT <= INIT_CNT+1;
            END IF;
        END IF;
    END PROCESS INIT_COUNTER;

При чём по каким-то неизвестным мне причинам если я меняю код контроллера, счётчик начинает правильно считать. Но счётчик никак не зависит от кода, который я меняю.....

image.png

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

SDRAM_CONTROLLER.vhd

Изменено пользователем Flip-fl0p

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


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

При чем если я вдруг решил сделать константу равной 3, а не 2.

CONSTANT TMRD            : INTEGER :=    3;

То счётчик работает правильно, но вот автомат прыгает в то состояние, в которое прыгать не должен... И команду выдает ту, которой не должно быть в этом состоянии. ( после состояния LOAD_MODE должно быть состояние NOPE_INIT и в это состоянии должна быть команда NOP...)

 

YE_RFR.png

Такое ощущение, что Quartus где-то делает "косяки" в выходных файлах и из за этого все проблемы.

 

Может я чего-то не знаю. Хотелось бы чтобы меня ткнули в мой косяк. Ибо мои мысли кончились....

Изменено пользователем Flip-fl0p

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


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

BEGIN

IF RISING_EDGE(CLK) THEN

IF (INIT_CNT < (TINIT+2*TRFC+TRP+3+1)) THEN

INIT_CNT <= INIT_CNT+1;

END IF;

END IF;

 

Ну, если меньше, то счетчик, а если равен или больше???

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


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

Ну, если меньше, то счетчик, а если равен или больше???

Пытался разные значения счетчику задавать.

Например досчитал до конца пусть считает заново:

 INIT_COUNTER:PROCESS
    (
        CLK
    )
    BEGIN
        IF RISING_EDGE(CLK) THEN
            IF (INIT_CNT < (TINIT+2*TRFC+TRP+3+1)) THEN
                INIT_CNT <= INIT_CNT+1;
            ELSE
                INIT_CNT <= 0;
            END IF;
            
        END IF;
    END PROCESS INIT_COUNTER;

То автомат просто залипает в состоянии PRECHARGE_INIT и игнорирует условие переключения с этого состояния.

WHEN PRECHARGE_INIT =>  IF (INIT_CNT = TINIT + TRP ) THEN                  -- Ждем времни TRP (precharge command period)
                                        NEXT_STATE <= REFRESH_INIT;                    -- Переводим автомат в состояние рефреша
                                    ELSE
                                        NEXT_STATE <= PRECHARGE_INIT;                  -- Иначе продолжаем ждать времени TRP 
                                    END IF;

 

 

image.png

 

Оператор NULL; ничего не дает, да и несинтезируется вроде.

 

Каждый раз присваивать максимальное значение счетчика, то-же не приносит результата. Получается не меньшая чушь.

 

image.png

 

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


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

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

Как минимум модель памяти отвечает на запросы:

ITS_LIFE.png

 

В качестве самообразования хотелось бы получить подсказку по TCL скриптам. Я в проекте активно использую пользовательский Radix например команды у меня отображаются в виде текста за счет того, что я создал пользовательский Radix при помощи TCL скрипта:

radix define CMD_RAM {
    "3'b111" "NOP" -color "Yellow",
    "3'b011" "ACTIVE" -color "Yellow",
    "3'b101" "READ" -color "Yellow",
    "3'b100" "WRITE" -color "Yellow",
    "3'b010" "PRECHARGE" -color "Yellow",
    "3'b001" "REFRESH" -color "Yellow",
    "3'b000" "LOAD REG" -color "Yellow",
    "3'b110" "BURST TERM" -color "Yellow",
    -default default
}

 

А можно ли как-то сделать так, чтобы длинные двоичные числа разделялись каким либо знаком.

Например есть двоичное число 1101010001000101010001 (где биты с 0 по 7 - адрес столбца, биты с 7 по 19 - адрес строки, биты с 20 по 21 номер банка) отображалось в виде 11_010100010001_01010001, а ещё лучше если бы в таком виде 3_1297_81 ( в 10 виде). Было бы гораздо проще работать с такими числами...

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


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

А можно ли как-то сделать так, чтобы длинные двоичные числа разделялись каким либо знаком.

Например есть двоичное число 1101010001000101010001 (где биты с 0 по 7 - адрес столбца, биты с 7 по 19 - адрес строки, биты с 20 по 21 номер банка) отображалось в виде 11_010100010001_01010001, а ещё лучше если бы в таком виде 3_1297_81 ( в 10 виде). Было бы гораздо проще работать с такими числами...

Насчёт этого не скажу.

Могу предложить разделить одну шину на несколько. В окне Wave в меню Тооls есть несколько способов: Combine Signals, Extract/pad bus, Split Bus.

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


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

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

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

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

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

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

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

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

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

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