Membrana Reference Version

Author: Claus Janicher 2025, Daniel Sommerfeldt 2026

The membrana_ref module is the main interface between the Nucleus and the Systembus. As Systembus this project uses Wishbone which is a well documented bus.

This module has a state-machine which performs the necessary tasks the processor is asking for. The program is in the current state stored in the built in Blockram module. This module is being created with the membrana_hw and only accessible via the IPort and DPort interface from the processor.

Functionally it works like the Membrana Hardware Variant, with the added possiblity of using Soft-Peripherals like the Membrana Software Variant. For this it is only necessary to set the correct flag (TECHS=sim).

../../_images/memu_core_perfect.png

Fig. 17 Diagram of the current implemented Hardware Membrana.

SC_MODULE(m_membrana_ref)

Reference-Membrana as the interface between the nucleus and the systembus.

This module is the reference-membrana unit which is used for the hardware and software implementation of the piconut processor. It is the interface between the Nucleus and the Systembus (Wishbone). Furthermore, it has a built in ram (Blockram) that serves as memory.

Author

Daniel Sommerfeldt

The interface for the module is expanded for a multi-nucleus system but not yet implemented. Open points:

  • fair next nucleus logic

  • on failed AMO use another nucleus

  • testing

Ports:

Parameters:
  • clk[in] clock of the module

  • reset[in] reset of the module

  • ip_stb[in] Instructionport Strobe

  • ip_adr[in] <32> Bit Instructionport Address

  • ip_bsel[in] Instructionport Byteselect

  • ip_rdata[out] Instructionport Read-Data

  • ip_ack[out] Instructionport ACK

  • dp_stb[in] Dataport strobe

  • dp_bsel[in] Dataport Byteselect

  • dp_adr[in] <32> Bit Dataport Address

  • dp_we[in] Dataport Write-Enable

  • dp_wdata[in] Dataport Write-Data

  • dp_rdata[out] Dataport Read-Data

  • dp_ack[out] Dataport ACK

  • dp_lr_sc[in] Dataport Load-Reserved/Store-Conditional (vector, per core)

  • dp_amo[in] Dataport Atomic Memory Operation (vector, per core)

  • wb_adr_o[out] Wishbone Address

  • wb_dat_o[out] Wishbone Data out

  • wb_dat_i[in] Wishbone Data in

  • wb_we_o[out] Wishbone Write-Enable out

  • wb_stb_o[out] Wishbone Strobe out

  • wb_cyc_o[out] Wishbone Cycle out

  • wb_ack_i[in] Wishbone ACK input

  • wb_sel_o[out] Wishbone Byte select

Integrated Blockram

SC_MODULE(m_membrana_ref_emem)

Blockram memory module for the membrana_ref.

This module is a dual-port blockram that is being used for code and memory storage of the piconut system.

Author

Claus Janicher, Gundolf Kiefer, Daniel Sommerfeldt

Ports:

Parameters:
  • clka[in] clock a of the module

  • clkb[in] clock b of the module

  • reset[in] reset of the module

  • wea[in] <4> Bit write enable for port a

  • web[in] <4> Bit write enable for port b

  • doa[out] <32> Bit data output port a

  • dob[out] <32> Bit data output port b

  • dia[in] <32> Bit data input port a

  • dib[in] <32> Bit data input port b

  • ena[in] enable signal for port a

  • enb[in] enable signal for port b

Interfaces

The main interface connections from the Membrana to the Nucleus processor are the IPort/DPort Interface bus systems. The other side of the Membrana is connected to the Wishbone Systembus, on which the membrana communicates as a Master.

Soft Peripheral Interface

void init_memory(uint64_t size, uint64_t base_adr)

Initializes the main system memory.

Parameters:
  • size – The total size of the memory block in bytes.

  • base_adr – The starting physical address for the memory allocation.

void load_elf(const std::string &elfFile)

Loads an ELF (Executable and Linkable Format) file into memory.

Parameters:

elfFile – Path to the ELF binary file.

void add_peripheral(uint64_t base_adr, std::unique_ptr<c_soft_peripheral> peripheral)

Registers a new peripheral into the system’s address space.

Parameters:
  • base_adr – The base memory-mapped address for the peripheral.

  • peripheral – A unique pointer to the peripheral instance.

c_soft_peripheral *find_peripheral(uint64_t address)

Locates a peripheral based on a specific memory address.

Parameters:

address – The memory address to check.

Returns:

c_soft_peripheral* Pointer to the peripheral if found, otherwise nullptr.

void write_peripheral(uint64_t address, uint32_t data, uint8_t bsel)

Performs a masked write to a peripheral.

Parameters:
  • address – The destination address.

  • data – The 32-bit data word to write.

  • bsel – Byte select bitmask.

uint32_t read_peripheral(uint64_t address, uint8_t bsel)

Reads data from a peripheral at a specific address.

Parameters:
  • address – The source address.

  • bsel – Byte select bitmask for the read operation.

Returns:

uint32_t The data read from the peripheral.

void list_all_peripherals()

Prints a list of all registered peripherals to the standard output.

int get_num_peripherals()

Retrieves the total count of registered peripherals.

Returns:

int The number of peripherals currently in the system.

c_soft_peripheral *get_peripheral(int index)

Accesses a peripheral by its registration index.

Parameters:

index – The index in the internal peripheral list.

Returns:

c_soft_peripheral* Pointer to the peripheral at the given index.

void on_rising_edge_clock_all_peripherals()

Signals a rising clock edge to every registered peripheral. Synchronizes the state of all soft peripherals with the system clock.

config-parameters in hw/piconut/config.mk

The BRAM size defines the size the internal blockram module has, which is being used for simulation and hardware synthesis. The START_ADDRESS is being used as a address subtraction method for the blockram, which doesn’t use the offset because its addresses start at 0x00000000.

  • CFG_START_ADDRESS = 0x10000000

  • CFG_MEMBRANA_BRAM_SIZE = 102399