Microblaze custom project

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 :slight_smile:

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?

1 Like

nevermind, was just a problem with Vitis IDE.
We will publish a new tutorial soon!