Dear all,
I am trying to create a new simple custom project with a single microblaze. The purpose of this project is to create a tutorial/workflow for the community
I have started a new project on Vivado 2020.1, I have created a hierarchy that contains the microblaze and the relative bram, and I have connected the bram block to the processing system through an Axi interconnect.
The complete design is described here:
design_1.pdf (189.4 KB)
I have also expanded the addressing of the BRAM in order to contain 16k of memory, as showed in this screenshot:
The program of the microblaze is very simple: when it receives a write command message (WRITE_LEDS), stores the value in a variable, and when it receives a read command message (READ_LEDS), return the value of the variable.
This is the code:
#include "circular_buffer.h"
// Work on 8-bit mode
#define WRITE_LEDS 0x5
#define READ_LEDS 0xB
int main(void)
{
unsigned char r = 60;
unsigned cmd = 0;
while(1){
// wait and store valid command
while((MAILBOX_CMD_ADDR & 0x01)==0);
cmd = MAILBOX_CMD_ADDR;
switch(cmd){
case WRITE_LEDS:
r = (u16) MAILBOX_DATA(0);
MAILBOX_CMD_ADDR = 0x0;
break;
case READ_LEDS:
MAILBOX_DATA(0) = r;
MAILBOX_CMD_ADDR = 0x0;
break;
default:
MAILBOX_CMD_ADDR = 0x0; // reset command
break;
}
}
return(0);
}
The code is successfully compiled with Vitis IDE.
Finally, this is the Jupyter notebook code:
from pynq import Overlay
from pynq.lib import PynqMicroblaze
ol = Overlay("design_1.bit")
customIOP = {
'ip_name': 'CustomIOP/axi_bram_ctrl_0',
'rst_name': "xlslice_0",
'intr_pin_name': "CustomIOP/dff_en_reset_vector_0/q",
'intr_ack_name': "xlslice_1"
}
MAILBOX_OFFSET = 0xF000
MAILBOX_SIZE = 0x1000
MAILBOX_PY2IOP_CMD_OFFSET = 0xffc
MAILBOX_PY2IOP_ADDR_OFFSET = 0xff8
MAILBOX_PY2IOP_DATA_OFFSET = 0xf00
WRITE_LEDS = 0x5
READ_LEDS = 0xB
import time
class MB(PynqMicroblaze):
def __init__(self, mb_info, mb_program):
super().__init__(mb_info, mb_program)
def write_mailbox(self, data_offset, data):
offset = MAILBOX_OFFSET + data_offset
self.write(offset, data)
def read_mailbox(self, data_offset, num_words=1):
offset = MAILBOX_OFFSET + data_offset
return self.read(offset, num_words)
def write_blocking_command(self, command):
self.write(MAILBOX_OFFSET + MAILBOX_PY2IOP_CMD_OFFSET, command)
while self.read(MAILBOX_OFFSET + MAILBOX_PY2IOP_CMD_OFFSET) != 0:
print(self.read(MAILBOX_OFFSET + MAILBOX_PY2IOP_CMD_OFFSET))
time.sleep(1)
pass
def write_blocking_command_addr(self, addr, command):
self.write(addr, command)
while self.read(addr) != 0:
pass
def write_non_blocking_command(self, command):
self.write(MAILBOX_OFFSET + MAILBOX_PY2IOP_CMD_OFFSET, command)
mb_info = customIOP
_mb = MB(mb_info, "test_main.bin")
_mb.write_blocking_command(READ_LEDS)
_mb.read_mailbox(0x0)
The Jupyter notebook stucks at the write_blocking_command function, because I see that the internal read returns always 11 (0xb, the READ_LEDS command).
It seems that the microblaze doesn’t receive anything from the mailbox or the bram, but I don’t know how to debug the program.
Do you have any advice about what is wrong with the flow/program?