nabbla (nabbla1) wrote,
nabbla
nabbla1

Categories:

Hello, world теперь на 25 МГц

И всё-таки ещё пару проверок для очистки совести. Мы же до этого всё время гоняли наш "быстрый QuatCore" на 4 МГц, а теперь хочется и на 25 МГц опробовать.

Ещё у меня дурацкая мысля возникла, что на ПЛИС, для этого "софтового" процессора не очень-то нужен вход reset, ведь он всё равно сбрасывает не всё. Если мы уже успели "затереть" что-нибудь в своей оперативной памяти, то reset это на место не вернёт, тут уж лучше всю ПЛИС сбросить, тогда она отконфигурируется по-новой, в том числе инициализирует содержимое блоков внутренней памяти. По счастью, достаточно лишь "заземлить" вход reset - и при синтезе всё ненужное уберётся.

И если рассчитывать, что с нулевого адреса программа запустится именно после инициализации ПЛИС, то все регистры и вся память имеют известное состояние. Иногда даже не просто "известное", но и заданное нами, чтобы не нужно было в коде программы их инициализировать. Не всегда, правда, вот счётчики lpm_counter всегда нулём инициализируются. Доходит до того, что в "чистом верилоге" мы регистр инициализировали, а синтезатор заметил, что здесь можно счётчик поставить - и всё, накрылась медным тазом наша инициализация. Не очень это правильно, но какая-то это "серая" тема с присвоением начальных значений...


Написали вот такую программу:
;проверяем UART на разогнанном до 25 МГц QuatCore
;сначала "повышаем частоту", затем выводим
%include "QuatCoreConsts.inc"
%include "Win1251.inc"
.rodata
	EthDisable	dw	2,3,0x22,0x54,0x00,0x01,3,0x22,0x66,0x00,0x18,2,0x22,0x6F,0x02
	hello		dw	'Hello, World! Live fast at 25 MHz',13,0x800A
.code
	main proc
		SetClock proc
		;конфигурирует Ethernet-контроллер на частоту 25 МГц и отключает собственно Ethernet
		;SP=0 при включении питания, на ПЛИС с этим строго
					SIO		ETH
					j		[SP++]	;количество посылок (счёт с нуля)
			@@EthWord:	k		[SP++]	;количество байт в посылке (счёт с нуля)
			@@EthByte:	OUT		[SP++]
					kLOOP		@@EthByte
					;нужно, чтобы nCS сбросилось в единицу
					NOP		IN
					jLOOP		@@EthWord
		SetClock endp
				SIO		UART
				SP		hello
				C		Call(print)
		@@endless:	JMP		@@endless
	main endp
	
	
	;посылает строку куда-нибудь. Пока модуль ввода-вывода всего один, SIO не нужен (нужный модуль по умолчанию будет активен)
	;X указывает на начало строки текста
	;конец обозначается отрицательным числом (у нас НЕТ ФЛАГА НУЛЯ!!!)
	;меняет значение регистра Acc и SP
	print proc
		@@start:	OUT		[SP]
				Acc		[SP++]
				SUB		0
				JGE		@@start
				JMP		C
	print endp


Вот её листинг:
    main proc
        SetClock proc
0  2002                      SIO     ETH
1  A1F3                      j       [SP++]  ;количество посылок (счёт с нуля)
2  A2F3              @@EthWord:  k       [SP++]  ;количество байт в посылке (счёт с нуля)
3  00F3              @@EthByte:  OUT     [SP++]
4  AA7D                      kLOOP       @@EthByte
5  8990                      NOP     IN
6  A97A                      jLOOP       @@EthWord
        SetClock endp
7  2000                  SIO     UART
8  FD0F                  SP      hello
9  8AB0                  C       Call(print)
A  B00A          @@endless:  JMP     @@endless
    main endp
    print proc
B  00FC          @@start:    OUT     [SP]
C  80F3                  Acc     [SP++]
D  8300                  SUB     0
E  BC7B                  JGE     @@start
F  B083                  JMP     C
    print endp


Влезает в 16 слов кода. Не стал инициализировать SP нулём, поскольку знаю и так, что он будет нулевым при начале работы, это как раз реверсивный счётчик, в явном виде выписанный как lpm_counter.

Да, удобная штука адресный регистр с автоинкрементом, жаль он пока всего один у нас, SP. Ну, пока хватает. Вызов функции пока сделали не через стек: адрес возврата заносится в регистр C, там он и лежит до лучших времён. Просто чтобы не забывать синтаксис своего транслятора и разные низкоуровневые штучки, которые здесь разрешены, ибо кто ж мне их запретит!

На удивление всё легко: код откомпилился с первого раза, без каких-либо Hazard'ов, затем я в QuatCore задал ширину ROM, 4 бита (!), ширину RAM, 5 бит, скопировал файлы QuatCoreCode.mif, QuatCoreData.mif и QuatCoreCallTable.v, запустил синтез, прошил - и вуаля:




Фурычит. И на 25 МГц мы наконец можем поставить частоту UART в 921600 бод, это деление частоты в 27 раз, получается с точностью 0,5%, это допустимо. С 4 МГц оно делиться правильно не хотело, разве что "дробный" делитель сделать, но всё равно же каждый бит тогда будет "дёргаться" из стороны в сторону, какой-то будет занимать 4 такта, какие-то 5 тактов, джиттер, так сказать.
Tags: ПЛИС, программки, работа, странные девайсы
Subscribe

Recent Posts from This Journal

  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 6 comments