I posted about my microcontroller design a couple of posts back. As it turns out, I had actually designed it wrong! I didn’t have the pipeline fully sorted meaning I couldn’t properly execute some instructions and some things weren’t working properly. After a quick stack overflow question, I realised the error of my ways and figured out what modifications I needed to make to my PC (program counter) implementation. The issue I was having was understanding how to account for the delay associated with using internal memories on my FPGA. Due to the registered address lines, the data from the ROM was delayed by up to 2 cycles which wasn’t being accounted for previously. This stopped pipeline stalls from working correctly and meant that what I thought was working… wasn’t actually working!

Surprisingly, even with the additional modifications, my microcontroller can synthesize and run at rates up to 74.94MHz! Not too bad if you ask me…

I’ve written a really quick USART implementation connected as a memory mapped peripheral. Its a bit buggy and doesn’t seem to properly work for streamed communications (byte directly after another byte) so I’ll need to iron out that bug, if however there is enough of a delay between sending bytes, all works correctly! The USART receiver side isn’t particularly well implemented as it doesn’t feature any input filtering so noisy inputs will produce strange data results!

Wahoo! Modelsim agrees

Ye ol’ logic analyser agrees too! sending the test byte 0b10101100 (USART is sent LSB first)

Hello world example
Here is an example that I’ve used to write the infamous “hello world!” to my logic analyzer through USART. It turns out that my USART implementation seemed buggy because I was accidentally inverting the status bit meaning my code thought the transfer had finished instantly, when actually it was just me reading the byte wrong! That’s been corrected and I can now successfully stream data!

Code listing:

stk 0
jmp ‘begin

str ra 2
rtm ra USART1_CTRL
str ra 1
rtm ra USART1_CTRL
str ra 434
str ra 12
rtm ra 1
str ra 0
rtm ra 0
jmp ‘load

mtr ra 0
mtr rb 1
alg sub rc rb ra
jpz rc ‘begin
str rb ‘darray
alg add rb ra rb
alg inc ra
rtm ra 0
stk 1
jpr rb
stk 0
jmp ‘start

rtm rd USART1_TXD
str ra 5
rtm ra USART1_CTRL
jmp ‘check

str rb 4
alg and rc ra rb
jpz rc ‘check
jmp ‘load

rtc rd “H”
rtc rd “E”
rtc rd “L”
rtc rd “L”
rtc rd “O”
rtc rd “_”
rtc rd “W”
rtc rd “O”
rtc rd “R”
rtc rd “L”
rtc rd “D”
rtc rd “!”

It currently takes up 46 program words of memory and just loops over and over printing “HELLO_WORLD!” to my logic analyzer. The reason I’m printing “HELLO_WORLD!” as opposed to “Hello world!” is because my assembler removes the whitespace and capitalizes all of the letters. A few code changes could solve that but hey ho, if it ain’t (too) broke, don’t fix it.

The magic value of 434 written to the USART1_BITCLKDIV register gives me a baud rate of 115200 and is the integer value of 50MHz/115200.

usarthelloworldHMCU to Logic analyzer, HELLO_WORLD!

Adding a new line character makes termite agree!

My next piece of VHDL design should hopefully be a memory mapped VGA controller! Obviously, it won’t be full colour and will likely be a poor resolution due to memory constraints though it should be a bit of fun!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s