Визуальная электроника

LatticeMico32 является 32-разрядным микропроцессором с soft core, разработанным Lattice Semiconductor и оптимизированным для программируемых вентильных матриц (FPGA). Он использует Гарвардскую архитектуру, что означает, что шины инструкции и данных являются отдельными. Логика арбитража шин может быть использована для объединения двух шин, при желании.

LatticeMico32 лицензируется по бесплатной лицензии. Это означает, что Mico32 не ограничивается ПЛИС Lattice, и может быть легально использован на любой хост-архитектуры (ПЛИС, asic или эмуляции программного обеспечения (например, в qemu)). Можно встроить LatticeMico32 ядра в ПЛИС xilinx и altera.

Давайте приступим к созданию этого процессора для нашей платы VE-LCMXO27000HC!

Для начала скачаем среду разработки с сайта Lattice

После установки запускаем LMS 1.0 for Diamond 3.10. На этом шаге нам необходимо выбрать путь к каталогу workspace:

pic1

Рис. 1: Создание нового проекта в LMS 1.0 for Diamond 3.10

Нажав OK мы увидим девственно чистое окно Eclipse:

pic2

Рис. 2: Новый проект

Выбираем File->New Platform. Откроется окно конфигурации новой платформы для конкретной FPGA платы. Указываем частоту установленного генератора- 50 МГц, требуемый процессор- LM32, тип установленной FPGA- LCMXO27000HC. Также укажем имя и папку для нашего проекта и выбираем FINISH

pic3

Рис. 3: Создание новой платформы FPGA платы

На левой панели мы видим возможные блоки, которые можно добавить к нашей SOC:

pic4

Рис. 4: Блоки SOC

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

pic5

Рис. 5: Процессор LatticeMico32

Далее добавим статическую память SRAM. Количество циклов чтения/записи необходимо установить равным 2. Ширина шины адреса 19 бит, шины данных 8 бит. Включаем Registered data output:

pic6

Рис. 6: Статическая память SRAM

В заключение добавим модуль вывода данных. Тип выберем Output Ports Only, ширину 32 бита:

pic7

Рис. 7: Модуль вывода данных GPIO

Далее соединим нашими модули с шинами данных и инструкций:

pic8

Рис. 8: Готовый микропроцессор LM32

Выбираем пункт меню Platform Tools->Run Generator. Если не допущено никаких ошибок мы получим сгенерированные файлы нашего проекта:

pic9

Рис. 9: Генерация файлов микропроцессор LatticeMico32

На этом настройка нашего проекта закончена. На следующем шаге добавим виртуальные индикаторы, из нашего предыдущего проекта Виртуальные светодиоды и 7-ми сегментный индикатор. Для этого добавим файлы display.v, hvsync.v, vga_leds.v а также создадим модуль синтезатора частоты pll с двумя частотами 74 МГц для VGA модуля и 100 МГц для процессора:

pic10

Рис. 10: Добавление файлов виртуальных индикаторов

Модуль верхнего уровня должен выглядеть следующим образом:

Verilog Code:
  1. module vga_leds(
  2. input wire CLK50MHZ,
  3. // outputs:
  4. output wire hsync,
  5. output wire vsync,
  6.  
  7. //high-color test video signal
  8. output wire [3:0]r,
  9. output wire [3:0]g,
  10. output wire [3:0]b,
  11.  
  12. //SRAM
  13. inout wire [7:0]sram_data,
  14. output wire [18:0]sram_adr,
  15. output wire sram_wen,
  16. output wire sram_oen,
  17. output wire sram_csn
  18. );
  19.  
  20. wire w_clk_video;
  21. wire w_clk_cpu;
  22. wire w_locked;
  23.  
  24. main_pll main_pll_inst(
  25. .CLKI(CLK50MHZ ),
  26. .CLKOP(w_clk_video ),
  27. .CLKOS(w_clk_cpu),
  28. .LOCK( w_locked)
  29. );
  30.  
  31. wire [31:0]counter;
  32.  
  33. mico_cpu mico_cpu_inst(
  34. .clk_i(w_clk_cpu),
  35. .reset_n(w_locked),
  36. .sramsram_wen(sram_wen),
  37. .sramsram_data(sram_data),
  38. .sramsram_addr(sram_adr),
  39. .sramsram_csn(sram_csn),
  40. .sramsram_be(),
  41. .sramsram_oen(sram_oen),
  42. .gpioPIO_OUT(counter)
  43. );
  44.  
  45.  
  46. display display_inst(
  47. .reset( ~w_locked ),
  48. .clk_video( w_clk_video ),
  49. .red_leds( counter[15:0] ),
  50. .green_leds( counter[15:0] ),
  51. .segments( counter[15:0] ),
  52. .hsync (hsync),
  53. .vsync (vsync),
  54. .r (r),
  55. .g (g),
  56. .b (b)
  57. );
  58.  
  59. endmodule

Компилируем наш проект:

pic11

Рис. 11: Синтезированный проект процессора LatticeMico32

Заливаем полученный битстрим в плату:

pic12

Рис. 12: Конфигурация платы VE-LCMXO27000HC

В принципе на этом этапе мы уже имеем работающий процессор! Но сам по себе он не представляет никакого интереса. Поэтому займемся созданием программы для нашего процессора. Для этого возвращаемся в Eclipse, переключаемся на вкладку C/C++ и выбираем File->New->Mico Managed Make C Project. Выбираем имя проекта led_test и в качестве шаблона применим LEDTest small size:

pic13

Рис. 13: Новый проект для LM32

В файле LEDTest_small_size.c меняем название порта GPIO с LED_BASE_ADDRESS на GPIO_BASE_ADDRESS. После этого наш код будет выглядеть следующим образом:

C++ Code:
  1. /**************************************************************
  2.  * This example exercises LEDs on LatticeMico32 Development *
  3.  * board. *
  4.  * *
  5.  * The implementation in this file is targeted for a size *
  6.  * smaller than the LEDTest template implementation. To *
  7.  * achieve this, the default LatticeDDInit function is over- *
  8.  * ridden by providing a DDInit.c in the project. *
  9.  * *
  10.  * Unlike LEDTest, f/printf functions are non-functional in *
  11.  * LEDTest_small_size *
  12.  * *
  13.  * *
  14.  *------------------------------------------------------------*
  15.  * PREREQUISITES: *
  16.  * *
  17.  * - GPIO with 8-bit output named LED connected to the *
  18.  * board's LED pins. *
  19.  * *
  20.  * - NOTE: IF YOU INTEND TO USE PRINTF, PLEASE MAKE CHANGES TO*
  21.  * DDINIT.C *
  22.  * *
  23.  **************************************************************/
  24. #include "MicoUtils.h"
  25. #include "system_conf.h"
  26.  
  27. int main(void)
  28. {
  29. unsigned char iValue = 0x1;
  30. unsigned char iShiftLeft = 1;
  31.  
  32. /* scroll the LEDs, every 100 msecs forever */
  33. while(1) {
  34. /* update GPIO output */
  35. *((volatile unsigned char*)(GPIO_BASE_ADDRESS)) = ~iValue;
  36.  
  37. /*
  38.   * sleep for approximately 100 msecs;
  39.   *
  40.   * NOTE: MicoSleepMilliSecs is not precise and
  41.   * can fluctuate significantly for processor configurations
  42.   * without caches
  43.   */
  44. MicoSleepMilliSecs(100);
  45.  
  46. /* determine next value */
  47. if (iShiftLeft == 1) {
  48. if (iValue == 0x80) {
  49. iShiftLeft = 0;
  50. iValue = 0x40;
  51. } else {
  52. iValue = iValue << 1;
  53. }
  54. } else {
  55. if (iValue == 0x01) {
  56. iShiftLeft = 1;
  57. iValue = 0x02;
  58. } else {
  59. iValue = iValue >> 1;
  60. }
  61. }
  62. }
  63.  
  64. /* all done */
  65. return(0);
  66. }

Выбираем Project->Build project:

pic14

Рис. 14: Результат компиляции

Осталось настроить отладку. Для этого выбираем Run->Debug configurations... В появившемся окне делаем двойной клик мышью на пункте mico32 hardware. Автоматически должна создаться конфигурация дебаггера:

pic15

Рис. 15: Настройка дебаггера

Жмем Debug! Если все настроено верно мы увидим окно отладки:

pic16

Рис. 16: Отладка проекта

Видео работы нашего процессора:

Проект дизайна микропроцессора LatticeMico32 для платы VE-LCMXO27000HC: mico_cpu.zip

Добавить комментарий