William Powers
Published

RFSoC 4x2 Quick Start to Hardware Acceleration

The following tutorial demonstrates how to quickly get a project up and running on the Xilinx RFSoC 4x2 FPGA board using the PYNQ framework.

IntermediateFull instructions provided2 hours1,062
RFSoC 4x2 Quick Start to Hardware Acceleration

Things used in this project

Hardware components

AMD Xilinx UltraScale+ RFSoC 4x2
×1

Software apps and online services

Vivado Design Suite
AMD Vivado Design Suite
PetaLinux
AMD PetaLinux

Story

Read more

Custom parts and enclosures

Full Vivado Project File (2023.1)

Schematics

Full Vivado Block Design Schematic

Code

Full Jupyter Notebook Utilizing Complex Multiplier

Python
# importing pynq library and Overlay class
import pynq
from pynq import Overlay
#__________________________________________________________________________________

# replace 'rfsoc_tutorial' with your <project-name>.bit
ol = Overlay("rfsoc_tutorial.bit")
print(ol)
#__________________________________________________________________________________

help(ol)


cmult = ol.cmult_0
help(cmult)
#__________________________________________________________________________________

# writing to cmult IP inputs a and b
def write_cmult(a=0, b=0):
    # writing to a
    # format = ar[32:16], ai[15:0]
    cmult.write(offset=0x00, value=a)
    # writing to b
    # format = br[32:16], bi[15:0]
    cmult.write(offset=0x04, value=b)

# reading from cmult IP outputs c_r and c_i
def read_cmult():
    # reading c real
    cr = cmult.read(offset=0x08)
    # reading c imaginary
    ci = cmult.read(offset=0x0c)
    print(f'int: {cr} + j{ci}')
    print(f'bin: {bin(cr)} + j{bin(ci)}')
#__________________________________________________________________________________

# (10+j10)*(10+j10) = (0+j200)
# 10100000000000001010 * 10100000000000001010 = 0 + j11001000
# 0xa000a * 0xa000a = 0 + j0xc8
write_cmult(0xa000a,0xa000a)
read_cmult()
#__________________________________________________________________________________

# (5+j5)*(3+j2) = (5+j25)
# 1010000000000000101 * 110000000000000010 = 101 + j11001
# 0x50005 * 0x30002 = 0x5 + j0x19
write_cmult(0x50005,0x30002)
read_cmult()
#__________________________________________________________________________________

# (444+j222)*(32+j24) = (8880+j19536)
# 1101111000000000011011110 * 1000000000000000011000 = 10001010110000 + j100110001010000
# 0x1bc00de * 0x200018 = 0x22b0 + j0x4c50
write_cmult(0x01bc00de,0x00200018)
read_cmult()
#__________________________________________________________________________________

Full Complex Multiplier Verilog

Verilog
`timescale 1ns / 1ps

module cmult #(
    parameter DATA_WIDTH = 32
)
(
    input wire [DATA_WIDTH-1:0] a,
    input wire [DATA_WIDTH-1:0] b,
    output reg [DATA_WIDTH-1:0] cr,
    output reg [DATA_WIDTH-1:0] ci
);
    
    wire signed [(DATA_WIDTH/2)-1:0] ar;
    wire signed [(DATA_WIDTH/2)-1:0] ai;
    wire signed [(DATA_WIDTH/2)-1:0] br;
    wire signed [(DATA_WIDTH/2)-1:0] bi;
    
    assign ar = a[DATA_WIDTH-1: 16];
    assign ai = a[(DATA_WIDTH/2)-1:0];   
    assign br = b[DATA_WIDTH-1: 16];
    assign bi = b[(DATA_WIDTH/2)-1:0];
    
    always@(a, b) begin
        cr = ar*br - ai*bi;
        ci = ar*br + ai*bi;
    end
    
endmodule

Credits

William Powers

William Powers

1 project • 5 followers
Undergraduate Computer Engineering Student at the University of Kansas.
Thanks to AMD Xilinx University Program and Carl Leuschen.

Comments