Trying to program BladeRF's FPGA with VHDL
Summary
I tried to implement the suggestions I got from Brian. And I was successful!
The first VHDL-program is possibly not synthesizable, but it works in the simulator. The next program more or less proves (I think) that I understood Brian's suggestions. The last program has the same behaviour and uses a table that is generated at compiletime. So, the synthesized program only has some precompiled data in a table. And that is synthesizable.
Testbed
library ieee ;
use
ieee.std_logic_1164.all ;
use
ieee.numeric_std.all ;
-- tdatasource.vhd
-- May-2014 Kees de Groot
-- test-program for the datasource to test my
DC-remover
-- this device simply tests the datasource
entity test_datasource is
PORT ( sdata
: out signed(11 downto 0));
end;
architecture mytest of test_datasource is
COMPONENT datasource
port (
reset : in std_logic;
clk : in std_logic;
sdata : out signed(11 downto 0)
) ;
END COMPONENT ;
SIGNAL clk :
std_logic := '1';
SIGNAL reset : std_logic := '0';
constant FS : real := 38.4e6 ; -- sample frequency
begin
dut : datasource
PORT MAP (
sdata =>
sdata,
clk =>
clk,
reset =>
reset );
clock : PROCESS(clk)
begin
clk <= not
clk after (1.0/FS)/2.0 * (1 sec) ;
end PROCESS clock;
stimulus : PROCESS
begin
wait for 5
ns; reset <= '1';
wait for 4
ns; reset <= '0';
wait;
end PROCESS stimulus;
end mytest;
a testbed is to be used with the simulator. So, does not have to be synthesizable, but should run correctly.
First floating/real program
library ieee ;
use
ieee.std_logic_1164.all ;
use
ieee.numeric_std.all ;
use
ieee.math_real.all;
-- datasource.vhd
-- May-2014 Kees de Groot
-- test-program for my DC-remover
-- this device outputs a 2s-complement sine of 32
points
entity datasource is
port (
reset : in std_logic;
clk : in std_logic;
sdata : out signed(11
downto 0)
) ;
end datasource;
architecture mydatasource of datasource is
signal indexx:
integer range 0 to 31;
signal
tmpdata: signed(11 downto 0);
begin
calcindex:
process (clk, reset)
begin
if
(reset='1') then
indexx <= 0;
elsif
(rising_edge(clk)) then
if
(indexx = 31) then
indexx <= 0;
else
indexx <= indexx +1;
end
if;
end
if;
end
process calcindex;
myproc:
process (indexx)
begin
tmpdata <= to_signed(600 + integer(1400.0
* SIN(2.0 * MATH_PI * real(indexx) / 32.0)), 12);
end
process myproc;
sdata
<= tmpdata;
end mydatasource;
Synthesizable floating/real program
library ieee ;
use
ieee.std_logic_1164.all ;
use
ieee.numeric_std.all ;
use
ieee.math_real.all;
-- datasource2.vhd
-- May-2014 Kees de Groot
-- test-program for my DC-remover
-- this device outputs a 2s-complement sine of 32
points
entity datasource is
port (
reset : in std_logic;
clk : in std_logic;
sdata : out signed(11
downto 0)
) ;
end datasource;
architecture mydatasource of datasource is
signal indexx:
integer range 0 to 31;
signal
tmpdata: signed(11 downto 0);
type sintab is
array(0 to 31) of signed(11 downto 0);
signal sinrom:
sintab;
begin
genrom: for
idx in 0 to 31 generate
constant x:
real := SIN(2.0 * MATH_PI * real(idx) / 32.0);
constant xn:
signed(11 downto 0) := to_signed(600 + integer(1400.0 * x), 12);
begin
sinrom(idx) <= xn;
end
generate;
calcindex:
process (clk, reset)
begin
if
(reset='1') then
indexx <= 0;
elsif
(rising_edge(clk)) then
if
(indexx = 31) then
indexx <= 0;
else
indexx <= indexx +1;
end
if;
end
if;
end
process calcindex;
myproc:
process (indexx)
begin
tmpdata <= sinrom(indexx);
end
process myproc;
sdata
<= tmpdata;
end mydatasource;
Picture of the simulation
One possible way is to calculate the table in VHDL at compile time, as
shown in the below example. (It's a 0..pi sine table, not the solution for your
problem).
Code:
TYPE SINTAB IS
ARRAY(0 TO ROMSIZE-1) OF STD_LOGIC_VECTOR (NNCO-2 DOWNTO 0);
SIGNAL SINROM:
SINTAB;
BEGIN
GENROM:
FOR idx in 0 TO
ROMSIZE-1 GENERATE
CONSTANT x: REAL :=
SIN(real(idx)*MATH_PI/real(ROMSIZE));
CONSTANT xn: UNSIGNED (NNCO-2 DOWNTO 0)
:= CONV_UNSIGNED(INTEGER(x*real(ROMMAX)),NNCO-1);
BEGIN
SINROM(idx) <= STD_LOGIC_VECTOR(xn);
END GENE
No comments:
Post a Comment