Zuse 0 May 18 Posted May 18 (edited) · Report post Всем привет. Пишу для Cyclone 3 на SV простенький RISC-V МК с однотактным процессором. За основу взял пример неполной реализации базового набора команд из книжки Харрисов. В примере есть память команд, представляющая собой массив 32-р слов. Инициализируется память так: $readmemh("Program.txt", RAM) В текстовом файле лежат подряд 32-р команды в шестнадцатеричном формате: 00000093 00108093 4000а113 .... Для пробы я написал на ассемблере небольшую программу, перевел ее в коды и записал коды в столбик, как в примере выше, но дальше хочу писать прошивки в какой-нибудь IDE и использовать для инициализации hex-файлы Вопрос: как инициализировать содержимое памяти hex-файлом? Edited May 18 by Zuse Quote Share this post Link to post Share on other sites More sharing options...
des00 14 May 18 Posted May 18 · Report post а чем корка ROM не устраивает? она же может инициализироваться из хекса Quote Share this post Link to post Share on other sites More sharing options...
Zuse 0 May 18 Posted May 18 · Report post 11 minutes ago, des00 said: а чем корка ROM не устраивает? она же может инициализироваться из хекса Я признаться новичок в теме и не владею сленгом. Что такое "корка" ? Quote Share this post Link to post Share on other sites More sharing options...
Lmx2315 1 May 18 Posted May 18 · Report post 13 минут назад, des00 сказал: а чем корка ROM не устраивает? она же может инициализироваться из хекса И каждый раз проект заново компилить? Quote Share this post Link to post Share on other sites More sharing options...
iosifk 3 May 18 Posted May 18 · Report post 2 часа назад, Zuse сказал: использовать для инициализации hex-файлы Вопрос: как инициализировать содержимое памяти hex-файлом? Hex2mif A script to convert hex instructions to Quartus .mif files · GitHub Quote Share this post Link to post Share on other sites More sharing options...
andrew_b 9 May 18 Posted May 18 · Report post 1 hour ago, Zuse said: Что такое "корка" IP core. Quote Share this post Link to post Share on other sites More sharing options...
iosifk 3 May 18 Posted May 18 · Report post 3 часа назад, Lmx2315 сказал: И каждый раз проект заново компилить? Для симуляции вроде не надо,,, Для релиза есть два стандартных пути: 1 сделать память двухпортовой и внешним автоматом из порта грузить команды 2 сделать программу загрузчик и по сбросу из порта грузить память команд 3 сделать монитор-загрузчик и вообще все отлаживать в программном режиме...т.е например при шаговой отладке переходить на теневое пзу и выдавать на хост содержание всех ресурсов процессора 1 Quote Share this post Link to post Share on other sites More sharing options...
xvr 11 May 18 Posted May 18 · Report post 7 hours ago, Zuse said: но дальше хочу писать прошивки в какой-нибудь IDE и использовать для инициализации hex-файлы eclipse + gcc + objcopy Quote Share this post Link to post Share on other sites More sharing options...
iosifk 3 May 18 Posted May 18 · Report post 4 часа назад, iosifk сказал: Для симуляции вроде не надо,,, Для релиза есть два стандартных пути: 1 сделать память двухпортовой и внешним автоматом из порта грузить команды 2 сделать программу загрузчик и по сбросу из порта грузить память команд 3 сделать монитор-загрузчик и вообще все отлаживать в программном режиме...т.е например при шаговой отладке переходить на теневое пзу и выдавать на хост содержание всех ресурсов процессора Ну а если "раскинуть остатками", то задается вопрос: а не хотите ли симулировать вообще без пзу? Т.е. вместо данных пзу ставим порт, адрес тоже выводим на порт. Команды записываем в файл и читаем из него код команды по адресу из порта адреса пзу... чтобмы не заморачиваться можно разделить клоки для чтения команд из файла и на клоки для процессора. Вычитали команду, посунули ее процессору и дали ему клок.., вот так точно проект каждый раз компилить не придется. Меняется только файл команд, а не сам процессор... Quote Share this post Link to post Share on other sites More sharing options...
des00 14 May 19 Posted May 19 · Report post 13 hours ago, Lmx2315 said: И каждый раз проект заново компилить? зачем? через житаг же можно залить. Например в том же пикоблейзе все есть, даже загрузка ПО на горячую. Сорцы доступны) 1 Quote Share this post Link to post Share on other sites More sharing options...
Zuse 0 May 19 Posted May 19 (edited) · Report post 17 hours ago, iosifk said: Hex2mif A script to convert hex instructions to Quartus .mif files · GitHub А разве $readmem переваривает .mif файлы? Но идея понятна - должен быть конвертер hex'а в формат, который понимает $readmem Edited May 19 by Zuse Quote Share this post Link to post Share on other sites More sharing options...
Zuse 0 May 19 Posted May 19 (edited) · Report post Только пока не удается нагуглить подходящий конвертер. Может, кто знает подходящий? UPD. Для истории: нужно гуглить "Intel HEX to Verilog converter" Edited May 19 by Zuse Quote Share this post Link to post Share on other sites More sharing options...
RobFPGA 10 May 19 Posted May 19 · Report post 1 hour ago, Zuse said: Но идея понятна - должен быть конвертер hex'а в формат, который понимает $readmem Так есть же $readmemh который сразу читает в hex. Quote Share this post Link to post Share on other sites More sharing options...
Zuse 0 May 19 Posted May 19 (edited) · Report post 49 minutes ago, RobFPGA said: Так есть же $readmemh который сразу читает в hex. Насколько понимаю, он читает не Intel-Hex, а файл шестнадцатеричных констант, разделенных пробелами/табами/энтерами Конвертер я таки нашел: https://github.com/dev-board-tech/intel-hex-to-rtl-mem Edited May 19 by Zuse Quote Share this post Link to post Share on other sites More sharing options...
BSACPLD 6 Friday at 09:19 AM Posted Friday at 09:19 AM · Report post 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 Quote Share this post Link to post Share on other sites More sharing options...