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

Инициализация памяти содержимым hex-файла

Всем привет.

Пишу для Cyclone 3 на SV простенький RISC-V МК с однотактным процессором. За основу взял пример неполной реализации базового набора команд из книжки Харрисов.

В примере есть память команд, представляющая собой массив 32-р слов.

Инициализируется память так: $readmemh("Program.txt", RAM)

В текстовом файле лежат подряд 32-р команды в шестнадцатеричном формате:

00000093

00108093

4000а113

....

Для пробы я написал на ассемблере небольшую программу, перевел ее в коды и записал коды в столбик, как в примере выше, но дальше  хочу писать прошивки в какой-нибудь IDE и использовать для инициализации hex-файлы

Вопрос: как инициализировать содержимое памяти hex-файлом?  

 

Изменено пользователем Zuse

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


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

а чем корка ROM не устраивает? она же может инициализироваться из хекса

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


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

11 minutes ago, des00 said:

а чем корка ROM не устраивает? она же может инициализироваться из хекса

Я признаться новичок в теме и не владею сленгом. Что такое "корка" ?

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


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

13 минут назад, des00 сказал:

а чем корка ROM не устраивает? она же может инициализироваться из хекса

И каждый раз проект заново компилить?

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


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

2 часа назад, Zuse сказал:

 использовать для инициализации hex-файлы

Вопрос: как инициализировать содержимое памяти hex-файлом?  

Hex2mif

A script to convert hex instructions to Quartus .mif files · GitHub

 

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


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

3 часа назад, Lmx2315 сказал:

И каждый раз проект заново компилить?

Для симуляции вроде не надо,,,

Для релиза есть два стандартных пути:

1 сделать память двухпортовой и внешним автоматом из порта грузить команды

2 сделать программу загрузчик и по сбросу из порта грузить память команд

3 сделать монитор-загрузчик и вообще все отлаживать в программном режиме...т.е например при шаговой отладке переходить на теневое пзу и выдавать на хост содержание всех ресурсов процессора

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


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

7 hours ago, Zuse said:

но дальше  хочу писать прошивки в какой-нибудь IDE и использовать для инициализации hex-файлы

eclipse + gcc + objcopy

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


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

4 часа назад, iosifk сказал:

Для симуляции вроде не надо,,,

Для релиза есть два стандартных пути:

1 сделать память двухпортовой и внешним автоматом из порта грузить команды

2 сделать программу загрузчик и по сбросу из порта грузить память команд

3 сделать монитор-загрузчик и вообще все отлаживать в программном режиме...т.е например при шаговой отладке переходить на теневое пзу и выдавать на хост содержание всех ресурсов процессора

Ну а если "раскинуть остатками", то задается вопрос: а не хотите ли симулировать вообще без пзу?

Т.е. вместо данных пзу ставим порт, адрес тоже выводим на порт. Команды записываем в файл и читаем из него код команды по адресу из порта адреса пзу... чтобмы не заморачиваться можно разделить клоки для чтения команд из файла и на клоки для процессора.

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

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


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

13 hours ago, Lmx2315 said:

И каждый раз проект заново компилить?

зачем? через житаг же можно залить. Например в том же пикоблейзе все есть, даже загрузка ПО на горячую. Сорцы доступны)

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


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

17 hours ago, iosifk said:

Hex2mif

A script to convert hex instructions to Quartus .mif files · GitHub

 

А разве $readmem переваривает .mif файлы?

Но идея понятна - должен быть конвертер hex'а в формат, который понимает $readmem

Изменено пользователем Zuse

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


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

Только пока не удается нагуглить подходящий конвертер. Может, кто знает подходящий?

UPD. Для истории: нужно гуглить "Intel HEX to Verilog converter"

Изменено пользователем Zuse

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


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

1 hour ago, Zuse said:

Но идея понятна - должен быть конвертер hex'а в формат, который понимает $readmem

Так есть же $readmemh  который сразу  читает в hex.   

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


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

49 minutes ago, RobFPGA said:

Так есть же $readmemh  который сразу  читает в hex.   

Насколько понимаю, он читает не Intel-Hex, а файл шестнадцатеричных констант, разделенных пробелами/табами/энтерами

Конвертер я таки нашел:

https://github.com/dev-board-tech/intel-hex-to-rtl-mem

Изменено пользователем Zuse

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


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

On 5/19/2023 at 11:23 AM, RobFPGA said:

$readmemh

Функции из Verilog позволяют инициализировать содержимое памяти, но в отсинтезированном проекте при их использовании нельзя обновлять содержимое памяти без пересборки всего проекта целиком - используйте готовый IP для RAM/ROM или мегафункцию altsyncram и сможете обновлять содержимое памяти всего парой команд: Processing->Update Memory Initialization File, Processing->Start->Start Assembler.

Вот пример:

`timescale 1 ns / 1 ps

module picorv32_prog_wrapper
#(
	parameter DATA_SIZE     = 8192,
	parameter DATA_WIDTH    =   32,
	parameter INIT_FILE     = "picorv32_fw.mem",
	parameter FPGA_VENDOR   = "SIM",
	parameter DEVICE_FAMILY = "SIM",
	parameter SIM_INIT      = "FALSE"
)
(
	input clock,
	input [$clog2(DATA_SIZE)-1:0] address,
	input [DATA_WIDTH-1:0] data,
	input wren,
	output [DATA_WIDTH-1:0] q
) ;


generate
if ((FPGA_VENDOR == "ALTERA") | (FPGA_VENDOR == "INTEL")) begin


altsyncram		#(
				.clock_enable_input_a   ("BYPASS"),
				.clock_enable_output_a  ("BYPASS"),
				.init_file              (INIT_FILE),
				.intended_device_family (DEVICE_FAMILY),
				.lpm_type               ("altsyncram"),
				.numwords_a             (DATA_SIZE),
				.operation_mode         ("SINGLE_PORT"),
				.outdata_aclr_a         ("NONE"),
				.outdata_reg_a          ("CLOCK0"),
				.power_up_uninitialized ("FALSE"),
				.widthad_a              ($clog2(DATA_SIZE)),
				.width_a                (DATA_WIDTH),
				.width_byteena_a        (1)
				)
				
				program_ram (
				.clock0                 (clock),
				.clock1                 (1'b1),
				.address_a              (address),
				.address_b              ({$clog2(DATA_SIZE){1'b0}}),
				.data_a                 (data),
				.data_b                 ({DATA_WIDTH{1'b0}}),
				.wren_a                 (wren),
				.wren_b                 (1'b0),
				.q_a                    (q),
				.q_b                    (),
				.aclr0                  (1'b0),
				.aclr1                  (1'b0),
				.byteena_a              (1'b1),
				.byteena_b              (1'b1),
				.addressstall_a         (1'b0),
				.addressstall_b         (1'b0),
				.clocken0               (1'b1),
				.clocken1               (1'b1),
				.clocken2               (1'b1),
				.clocken3               (1'b1),
				.rden_a                 (1'b1),
				.rden_b                 (1'b1),
				.eccstatus              ()
				) ;


end
else if (FPGA_VENDOR == "XILINX") begin


xpm_memory_spram #(
				.ADDR_WIDTH_A           ($clog2(DATA_SIZE)),
				.AUTO_SLEEP_TIME        (0),
				.BYTE_WRITE_WIDTH_A     (DATA_WIDTH),
				.CASCADE_HEIGHT         (0),
				.ECC_MODE               ("no_ecc"),
				.MEMORY_INIT_FILE       (INIT_FILE),
				.MEMORY_INIT_PARAM      ("0"),
				.MEMORY_OPTIMIZATION    ("false"),
				.MEMORY_PRIMITIVE       ("block"),
				.MEMORY_SIZE            (DATA_WIDTH*DATA_SIZE),
				.MESSAGE_CONTROL        (0),
				.READ_DATA_WIDTH_A      (DATA_WIDTH),
				.READ_LATENCY_A         (2),
				.READ_RESET_VALUE_A     ("0"),
				.RST_MODE_A             ("ASYNC"),
				.SIM_ASSERT_CHK         (0),
				.USE_MEM_INIT           (1),
				.WAKEUP_TIME            ("disable_sleep"),
				.WRITE_DATA_WIDTH_A     (DATA_WIDTH),
				.WRITE_MODE_A           ("no_change")
				)
				
				program_ram (
				.dbiterra               (),
				.douta                  (q),
				.sbiterra               (),
				.addra                  (address),
				.clka                   (clock),
				.dina                   (data),
				.ena                    (1'b1),
				.injectdbiterra         (1'b0),
				.injectsbiterra         (1'b0),
				.regcea                 (1'b1),
				.rsta                   (1'b0),
				.sleep                  (1'b0),
				.wea                    (wren)
				) ;


end
else if (FPGA_VENDOR == "LATTICE") begin


pmi_ram_dq		#(
				.pmi_addr_width         ($clog2(DATA_SIZE)),
				.pmi_addr_depth         (DATA_SIZE),
				.pmi_data_width         (DATA_WIDTH),
				.pmi_regmode            ("reg"),
				.pmi_gsr                ("disable"),
				.pmi_resetmode          ("async"),
				.pmi_optimization       ("speed"),
				.pmi_init_file          (INIT_FILE),
				.pmi_init_file_format   ("hex"),
				.pmi_write_mode         ("normal"),
				.pmi_family             (DEVICE_FAMILY)
				)
				
				program_ram (
				.Reset                  (1'b0),
				.Clock                  (clock),
				.ClockEn                (1'b1),
				.Address                (address),
				.Data                   (data),
				.WE                     (wren),
				.Q                      (q)
				) ;


end
else begin


end
endgenerate


endmodule

 

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


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

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

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

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

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

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

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

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

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

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