Menu Close

RISC-V Bus and Pipeline(1)Introduction to Bus

1. Introduction to Bus

Related reference articles:

RISC-V Syllabus


In computing, a bus (originally from Latin word, omnibus) is a communication system that transfers data between components inside a computer, or between computers [1]. It is usually a transmission wire harness composed of wires. According to the types of information transmitted by the computer, the computer bus can be divided into data bus, address bus, and control bus respectively used to transmit data, address, and control signals.

There is some bus classifications. For example, based on the bus’s primary role, connecting devices internally or externally, there are internal buses and external buses. SPI and I2C are internal buses, while Firewire (IEEE 1394) and GPIB (IEEE-488) are external buses. Also, the classification could be based on the data transmission form, buses could be either serial or parallel. Serial buses carry data word in parallel on multiple wires, and serial buses carry data in the bit-serial form. For instance, PCI-E and USB are serial buses, while ISA and wishbone are parallel.

The reason why using buses is to standardize the data format of both input and output, so that the data communication between CPU and peripherals, peripherals and peripherals does not depend on its own data format. Since there are a huge amount of different peripherals, so as the data format of peripherals, it is vital to adopt on the same standard. When the computer accesses multiple peripherals, like printers, microphones, keyboards, as long as the computer is using the USB protocol, and cooperate with the corresponding software, the peripherals can work without designing varies of interfaces connecting with the computer. In this way, the design of different interfaces has been eliminated, and the design of the computer and the peripherals are separated and simplified.

RAM, FIFO, FLASH and etc. are all FPGA’s internal logic, but they have different modules and communication interfaces. Below are the interface modules of RAM and FIFO.

//RAM module
//single port RAM, could be dual_port

TSP_RAM     your_instance_name 
  .clka     (clka),     // input wire clka
  .wea      (wea),      // input wire [0 : 0] wea
  .addra    (addra),    // input wire [11 : 0] addra
                        // the second time to instantiate RAM, may require a different length of address

  .dina     (dina),     // input wire [31 : 0] dina
  .douta    (douta),    // output wire [31 : 0] douta

//FIFO module
fifo_generator     your_instance_name (
  .clk      (clk),      // input wire clk
  .srst     (srst),     // input wire srst, reset
  .din      (din),      // input wire [7 : 0] din
  .wr_en    (wr_en),    // input wire wr_en
  .rd_en    (rd_en),    // input wire rd_en
  .dout     (dout),     // output wire [7 : 0] dout
                        // FIFO full/empty
  .full     (full),     // output wire full
  .empty    (empty)     // output wire empty


CPU needs to connect both RAM and FIFO, while it is obvious that they have different data lengths and different address formats. If the CPU does not need to design every specific interface with each, a lot of time is saved for designing the CPU itself, instead of designing the connection with peripherals. Here is an example of RISCV CPU load and store module:


    i_D_PC,          // peripherals address (like FIFO, RAM)
    i_LOAD,          // load instruction
    i_load_instr,    // {rv32i_lbu,rv32i_lb,rv32i_lhu,rv32i_lh,rv32i_lw};
    o_rd_wen,        // read, write enable
    i_rd_idx,        // register index, used to write back
    o_wb_data,       // write back data
    i_STORE,         // store instruction
    i_store_instr,   // {rv32i_sb,rv32i_sh,rv32i_sw};
    i_rs2_val,       // actual value stored on the peripherals


It can be seen that the CPU interface is also different from the peripherals. Furthermore, the peripherals are always developing. Without bus, even the CPU is considering every peripheral when it is initially designed, with the expansion of peripherals, it will eventually cause trouble.

Assume there is no bus between CPU and peripherals, then some issues need to be resolved.

  • Convert the instruction information decoded by the CPU into the signal required by the RAM interface. And convert the instruction information decoded by the CPU into the signal required by the FIFO interface
  • Clock mismatch. The peripheral may be a super low-speed device, or a device that can get data in multiple clock cycles (e.g. DDR needs tens of clocks to read or write data one time)
  • RISCV CPU designers have to deal with different peripherals one by one. In this way, CPU core designers and peripheral IP designers must cooperate. Many projects are completed by multiple developers or multiple companies, which increases service communication costs.

The solution is to use the bus. The benefits are as follows:

  • With the same standard, no need to care about the peripheral interfaces
  • No need to care about the clock mismatch between the CPU and peripherals
  • The CPU designer concentrates on designing the CPU core. Peripheral developers pay attention to related development of peripherals. Everyone abides by the bus specification and can easily achieve interconnection.
  • The bus can be expanded and interconnected. For example, the FII-RISCV bus can be expanded as AHB, while the current bus structure will not be destroyed, and the IP core previously connected by AHB can be used directly.
  • It is very helpful in tailoring the peripheral as well. CPU does not need to change, only the address is updated, and the chip is tailored.

In all, the bus is necessary as an agreed standard and is a solution from practice.


Posted in Application and Development, Articles, RISC-V, RISC-V Textbook, Textbook and Training Project

Related Articles

Leave a Reply

Your email address will not be published.

Leave the field below empty!