Skip to content

Instantly share code, notes, and snippets.

@punzik
Created December 29, 2023 14:28
Show Gist options
  • Save punzik/05063d321306cf66154e6198feada534 to your computer and use it in GitHub Desktop.
Save punzik/05063d321306cf66154e6198feada534 to your computer and use it in GitHub Desktop.
Yosys DPI
LIB_NAME = my_lib
SOURCES = my_lib.c
$(LIB_NAME).so: $(SOURCES)
gcc -O2 -shared -o $(LIB_NAME).so $(SOURCES)
#include <stdio.h>
#include <string.h>
#include <math.h>
int clog2(int x)
{
return (int)ceil(log2(x));
}
static void strrev_inplace(char *str)
{
char t;
int l = 0;
int r = strlen(str) - 1;
while (l < r) {
t = str[l];
str[l++] = str[r];
str[r--] = t;
}
}
static void chandle_string(unsigned long prefix, char *s)
{
s[8] = '\0';
strncpy(s, (char*)(&prefix), 8);
strrev_inplace(s);
}
int print_int1(unsigned long prefix, int val)
{
char s[9];
chandle_string(prefix, s);
printf("--- %s %i\n", s, val);
return val;
}
int print_int2(unsigned long prefix, int val1, int val2)
{
char s[9];
chandle_string(prefix, s);
printf("--- %s %i %i\n", s, val1, val2);
return val1;
}
int sin_int(int phase, int phase_scale, int output_scale)
{
double a = 2.0 * M_PI * (double)phase / (double)phase_scale;
double s = sin(a) * (double)output_scale;
return (int)s;
}
int ceiling(double x)
{
return (int)ceil(x);
}
static int iter_i;
static int iter_limit;
void iter_init(int limit)
{
iter_i = 0;
iter_limit = limit;
}
int iter(void)
{
int ii = iter_i;
if (++iter_i >= iter_limit) iter_i = 0;
return ii;
}
int iterator(int limit)
{
static int i = 0;
int ii = i;
if (++i >= limit) i = 0;
return ii;
}
module yosys_dpi_test #(parameter SIZE = 100)
(clock, i_addr, o_data);
import "DPI-C" function integer clog2 (integer);
import "DPI-C" function integer sin_int (integer, integer, integer);
import "DPI-C" function integer ceiling (real);
import "DPI-C" function integer iterator (integer);
import "DPI-C" function integer iter_init (integer); // void function
import "DPI-C" function integer iter;
localparam AWIDTH = clog2(SIZE);
localparam TWOPI = ceiling(3.1415926 * 2.0);
localparam I0 = iterator(10);
localparam I1 = iterator(10);
initial begin
integer unused, N0, N1;
unused = iter_init(20);
N0 = iter();
N1 = iter();
end
initial begin
$display("SIZE = %0d", SIZE);
$display("AWIDTH = %0d", AWIDTH);
end
input wire clock;
input wire [AWIDTH-1:0] i_addr;
output reg [7:0] o_data;
logic signed [7:0] rom[SIZE];
initial begin
for (int n = 0; n < SIZE; n ++)
rom[n] = 8'(sin_int(n, SIZE, 127));
end
always_ff @(posedge clock)
o_data <= rom[i_addr];
endmodule
plugin -i my_lib.so
read -sv2012 yosys_dpi_test.sv
hierarchy -check -top yosys_dpi_test
proc
synth_ice40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment