new fpga firmware - sorry, only one blob

new features:

- bit to swap I and Q (spectrum inversion)

- make GPS PPS input usable as clock reference (PPS acts as clock gate
  for a counter)

- change unused pins into GPIOs (input, output, etc. configuration via
  SPI register bank)

- LED connected to FPGA can be switched on and off

have a look at the updated register description ODF/PDF
master
Christian Daniel 11 years ago
parent 1c329c8165
commit 83340d0b37
  1. 3
      fpga/hw-v2/compilation.order
  2. 6
      fpga/hw-v2/compile.cfg
  3. BIN
      fpga/hw-v2/deploy/usbrx_data.vme
  4. BIN
      fpga/hw-v2/deploy/usbrx_fpga_regs.odt
  5. BIN
      fpga/hw-v2/deploy/usbrx_fpga_regs.pdf
  6. 12
      fpga/hw-v2/diamond/usbrx_vhdl.ldf
  7. 4
      fpga/hw-v2/diamond/usbrx_vhdl.lpf
  8. 12
      fpga/hw-v2/src/mt_toolbox/mt_clktools.vhd
  9. 135
      fpga/hw-v2/src/mt_toolbox/mt_synctools.vhd
  10. 7
      fpga/hw-v2/src/mt_toolbox/mt_toolbox.vhd
  11. 22
      fpga/hw-v2/src/testbench/tb_usbrx.vhd
  12. 47
      fpga/hw-v2/src/usbrx/datapath/usbrx_offset.vhd
  13. 15
      fpga/hw-v2/src/usbrx/toplevel/usbrx_clkgen.vhd
  14. 158
      fpga/hw-v2/src/usbrx/toplevel/usbrx_clkref.vhd
  15. 72
      fpga/hw-v2/src/usbrx/toplevel/usbrx_gpio.vhd
  16. 62
      fpga/hw-v2/src/usbrx/toplevel/usbrx_regbank.vhd
  17. 128
      fpga/hw-v2/src/usbrx/toplevel/usbrx_toplevel.vhd
  18. 26
      fpga/hw-v2/src/usbrx/usbrx.vhd
  19. 11
      fpga/hw-v2/stimulators.set
  20. 1
      fpga/hw-v2/synthesis.order
  21. 8
      fpga/hw-v2/usbrx_vhdl.adf
  22. 63
      fpga/hw-v2/usbrx_vhdl.wsp

@ -1,5 +1,6 @@
.\src\mt_toolbox\mt_toolbox.vhd
.\src\mt_toolbox\mt_clktools.vhd
.\src\mt_toolbox\mt_synctools.vhd
.\src\mt_filter\mt_filter.vhd
.\src\mt_filter\mt_fil_storage_slow.vhd
.\src\mt_filter\mt_fil_mac_slow.vhd
@ -11,6 +12,8 @@
.\src\usbrx\datapath\usbrx_decimate.vhd
.\src\usbrx\datapath\usbrx_ssc.vhd
.\src\usbrx\toplevel\usbrx_clkgen.vhd
.\src\usbrx\toplevel\usbrx_clkref.vhd
.\src\usbrx\toplevel\usbrx_gpio.vhd
.\src\usbrx\toplevel\usbrx_spi.vhd
.\src\usbrx\toplevel\usbrx_regbank.vhd
.\src\usbrx\toplevel\usbrx_pwm.vhd

@ -44,3 +44,9 @@ Enabled=1
LIB=
Enabled=1
VerilogLanguage=7
[file:.\src\usbrx\toplevel\usbrx_clkref.vhd]
Enabled=1
[file:.\src\mt_toolbox\mt_synctools.vhd]
Enabled=1
[file:.\src\usbrx\toplevel\usbrx_gpio.vhd]
Enabled=1

Binary file not shown.

@ -54,13 +54,19 @@
<Source name="../src/mt_toolbox/mt_clktools.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../deploy/usbrx.xcf" type="ispVM Download Project" type_short="ispVM" excluded="TRUE">
<Source name="../src/mt_toolbox/mt_synctools.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="usbrx_vhdl.lpf" type="Logic Preference" type_short="LPF">
<Source name="../src/usbrx/toplevel/usbrx_clkref.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="../src/usbrx/toplevel/usbrx_gpio.vhd" type="VHDL" type_short="VHDL">
<Options/>
</Source>
<Source name="usbrx_vhdl/usbrx_vhdl.xcf" type="ispVM Download Project" type_short="ispVM">
<Source name="../deploy/usbrx.xcf" type="ispVM Download Project" type_short="ispVM" excluded="TRUE">
<Options/>
</Source>
<Source name="usbrx_vhdl.lpf" type="Logic Preference" type_short="LPF">
<Options/>
</Source>
</Implementation>

@ -32,6 +32,7 @@ LOCATE COMP "gpio_6" SITE "A9" ;
LOCATE COMP "gpio_7" SITE "A10" ;
LOCATE COMP "gpio_8" SITE "A11" ;
LOCATE COMP "gpio_9" SITE "A13" ;
LOCATE COMP "led" SITE "M7" ;
LOCATE COMP "vgnd_0" SITE "B3" ;
LOCATE COMP "vgnd_1" SITE "C5" ;
LOCATE COMP "vgnd_2" SITE "C8" ;
@ -83,7 +84,7 @@ IOBUF PORT "tx_syn" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "tx_dat" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gain0" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gain1" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gps_1pps" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gps_1pps" IO_TYPE=LVCMOS33 ;
IOBUF PORT "gpio_0" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gpio_1" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gpio_2" IO_TYPE=LVCMOS33 DRIVE=4 ;
@ -94,6 +95,7 @@ IOBUF PORT "gpio_6" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gpio_7" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gpio_8" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "gpio_9" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "led" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vgnd_0" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vgnd_1" IO_TYPE=LVCMOS33 DRIVE=4 ;
IOBUF PORT "vgnd_2" IO_TYPE=LVCMOS33 DRIVE=4 ;

@ -35,12 +35,7 @@ entity mt_reset_gen is
ext_rst : in std_logic; -- external reset
pll_locked : in std_logic; -- PLLs locked?
reset_pll : out std_logic; -- reset signal for PLLs
reset_sys : out std_logic; -- global reset signal
-- debug
dbg_ext : out std_logic;
dbg_rst : out std_logic;
dbg_lock : out std_logic
reset_sys : out std_logic -- global reset signal
);
end mt_reset_gen;
@ -112,11 +107,6 @@ begin
-- output PLL-reset
reset_pll <= reset_pll_i;
-- debug
dbg_ext <= ext_rst;
dbg_rst <= reset_pll_i;
dbg_lock <= pll_locked;
end;

@ -0,0 +1,135 @@
-----------------------------------------------------------------------------------
-- Filename : mt_synctools.vhd
-- Project : maintech IP-Core toolbox
-- Purpose : Basic tools for clock-domain-crossings
--
-----------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- This program is free software; you can redistribute it and/or modify --
-- it under the terms of the GNU General Public License as published by --
-- the Free Software Foundation as version 3 of the License, or --
-- --
-- This program is distributed in the hope that it will be useful, --
-- but WITHOUT ANY WARRANTY; without even the implied warranty of --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --
-- GNU General Public License V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
------------------------------------------------------------------------------
-- mt_sync_dualff (dual flip-flop synchronizer) -------------------------------
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.mt_toolbox.all;
entity mt_sync_dualff is
port(
-- input
i_data : in std_logic;
-- output
o_clk : in std_logic;
o_data : out std_logic
);
end mt_sync_dualff;
architecture rtl of mt_sync_dualff is
-- signals
signal sreg : std_logic := '0';
signal oreg : std_logic := '0';
-- no SRL16s here...
attribute shreg_extract of sreg : signal is "no";
attribute shreg_extract of oreg : signal is "no";
begin
process(o_clk)
begin
if rising_edge(o_clk) then
sreg <= i_data;
oreg <= sreg;
end if;
end process;
o_data <= oreg;
end rtl;
-------------------------------------------------------------------------------
-- mt_sync_feedback (feedback synchronizer) -----------------------------------
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
library work;
use work.mt_toolbox.all;
entity mt_sync_feedback is
port(
-- input
i_clk : in std_logic;
i_data : in std_logic;
-- output
o_clk : in std_logic;
o_data : out std_logic
);
end mt_sync_feedback;
architecture rtl of mt_sync_feedback is
signal flip_i : std_logic := '0';
signal flip_s1 : std_logic := '0';
signal flip_s2 : std_logic := '0';
signal flip_s3 : std_logic := '0';
signal oreg : std_logic := '0';
attribute syn_keep of flip_i : signal is true;
attribute syn_keep of flip_s1 : signal is true;
attribute syn_keep of flip_s2 : signal is true;
attribute syn_keep of flip_s3 : signal is true;
attribute syn_keep of oreg : signal is true;
begin
process(i_clk)
begin
if rising_edge(i_clk) then
-- update flip-bit on request
if i_data='1' then
flip_i <= not flip_i;
end if;
-- debug check
assert not (i_data='1' and flip_s1/=flip_i)
report "mt_sync_feedback: pulses too close, failed to synchronize"
severity failure;
end if;
end process;
process(o_clk)
begin
if rising_edge(o_clk) then
-- synchronize flip-bit
flip_s1 <= flip_i;
flip_s2 <= flip_s1;
flip_s3 <= flip_s2;
-- create output-request
oreg <= flip_s3 xor flip_s2;
end if;
end process;
-- set output
o_data <= oreg;
end rtl;

@ -72,9 +72,10 @@ package mt_toolbox is
--
-- common attributes
--
attribute syn_keep : boolean;
attribute syn_ramstyle : string;
attribute syn_romstyle : string;
attribute syn_keep : boolean;
attribute syn_ramstyle : string;
attribute syn_romstyle : string;
attribute shreg_extract : string;
end mt_toolbox;

@ -95,12 +95,32 @@ begin
tx_dat <= '0';
-- GPS
gps_1pps <= '0';
-- gps_1pps <= '0';
gps_10k <= '0';
-- gpios
gpio <= (others=>'H');
-- generate pps signal
-- (set every millisecond instead of every second
-- to speed to simulation time)
process
variable cnt : natural;
begin
gps_1pps <= '0';
cnt := 1;
loop
wait for (cnt * 1 ms) - now;
gps_1pps <= '1';
wait for 1us;
gps_1pps <= '0';
cnt := cnt+1;
end loop;
wait;
end process;
-- dummy ADC model
process
-- constant word1 : unsigned(15 downto 0) := "0010000000000001";

@ -54,25 +54,33 @@ architecture rtl of usbrx_offset is
-- clip & saturate sample
function doClipValue(x : signed) return signed is
variable xnorm : signed(x'length-1 downto 0) := x;
begin
if x >= 32768 then
if xnorm >= 32768 then
-- overflow
return to_signed(+32767,16);
elsif x < -32768 then
elsif xnorm < -32768 then
-- underflow
return to_signed(-32768,16);
else
-- in range
return x(15 downto 0);
return xnorm(15 downto 0);
end if;
end doClipValue;
-- multiplier input
signal mula_i, mula_q : signed(17 downto 0) := (others=>'0');
signal mulb_i, mulb_q : signed(17 downto 0) := (others=>'0');
-- multiplier output
signal mout_i, mout_q : signed(18 downto 0) := (others=>'0');
begin
-- control logic
process(clk)
variable s16i, s16q : signed(15 downto 0);
variable s17i, s17q : signed(16 downto 0);
variable mtmp_i, mtmp_q : signed(35 downto 0);
variable atmp_i, atmp_q : signed(19 downto 0);
begin
if rising_edge(clk) then
-- passthough clock
@ -80,17 +88,30 @@ begin
-- handle data
if in_clk='1' then
-- convert input into 16bit signed
s16i := signed(in_i xor "10000000000000") & "00";
s16q := signed(in_q xor "10000000000000") & "00";
-- apply swap-flag & convert input into 18bit signed
if config.swap='0' then
mula_i <= signed(in_i xor "10000000000000") & "0000";
mula_q <= signed(in_q xor "10000000000000") & "0000";
else
mula_i <= signed(in_q xor "10000000000000") & "0000";
mula_q <= signed(in_i xor "10000000000000") & "0000";
end if;
-- apply gain
mulb_i <= signed("00" & config.igain);
mulb_q <= signed("00" & config.qgain);
mtmp_i := mula_i * mulb_i;
mtmp_q := mula_q * mulb_q;
mout_i <= mtmp_i(34 downto 16);
mout_q <= mtmp_q(34 downto 16);
-- add offset
s17i := resize(s16i,17) + resize(config.ioff,17);
s17q := resize(s16q,17) + resize(config.qoff,17);
-- add offset (also adds 0.5 for rounding of multiplier-output)
atmp_i := resize(mout_i,20) + resize(config.ioff&"1",20);
atmp_q := resize(mout_q,20) + resize(config.qoff&"1",20);
-- clip output
out_i <= doClipValue(s17i);
out_q <= doClipValue(s17q);
out_i <= doClipValue(atmp_i(19 downto 1));
out_q <= doClipValue(atmp_q(19 downto 1));
end if;
-- handle reset

@ -42,12 +42,7 @@ entity usbrx_clkgen is
clk_30 : out std_logic; -- 30MHz clock
clk_80 : out std_logic; -- 80MHz clock
rst_30 : out std_logic; -- 30MHz reset
rst_80 : out std_logic; -- 80MHz reset
-- debug
dbg_ext : out std_logic;
dbg_rst : out std_logic;
dbg_lock : out std_logic
rst_80 : out std_logic -- 80MHz reset
);
end usbrx_clkgen;
@ -94,13 +89,7 @@ begin
ext_rst => ext_rst,
pll_locked => pll_locked,
reset_pll => rst_pll,
reset_sys => reset_i,
-- debug
dbg_ext => dbg_ext,
dbg_rst => dbg_rst,
dbg_lock => dbg_lock
reset_sys => reset_i
);
-- sync reset to clock-domains

@ -0,0 +1,158 @@
---------------------------------------------------------------------------------------------------
-- Filename : usbrx_clkref.vhd
-- Project : OsmoSDR FPGA Firmware
-- Purpose : Reference Clock Measurement
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- This program is free software; you can redistribute it and/or modify --
-- it under the terms of the GNU General Public License as published by --
-- the Free Software Foundation as version 3 of the License, or --
-- --
-- This program is distributed in the hope that it will be useful, --
-- but WITHOUT ANY WARRANTY; without even the implied warranty of --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --
-- GNU General Public License V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.all;
use work.mt_toolbox.all;
use work.usbrx.all;
entity usbrx_clkref is
port(
-- system clocks
clk_sys : in std_logic;
rst_sys : in std_logic;
-- reference signal
clk_ref : in std_logic;
rst_ref : in std_logic;
-- 1pps signal
gps_1pps : in std_logic;
-- status
status : out usbrx_ref_status_t
);
end usbrx_clkref;
architecture rtl of usbrx_clkref is
-- deglitcher
signal dgl_hist : std_logic_vector(3 downto 0);
signal dgl_out : std_logic;
-- edge detection
signal pps_last : std_logic;
-- active counters
signal cnt_lsb : unsigned(24 downto 0);
-- latched counters
signal lat_upd : std_logic;
signal lat_lsb : unsigned(24 downto 0);
signal lat_msb : unsigned(6 downto 0);
-- output register
signal out_upd : std_logic;
signal out_lsb : unsigned(24 downto 0);
signal out_msb : unsigned(6 downto 0);
begin
-- reference counter
process(clk_ref)
variable cnt0,cnt1 : natural range 0 to 4;
variable re : boolean;
begin
if rising_edge(clk_ref) then
-- set default values
lat_upd <= '0';
-- deglitch pps signal
dgl_hist <= dgl_hist(dgl_hist'left-1 downto 0) & gps_1pps;
cnt0 := 0;
cnt1 := 0;
for i in dgl_hist'range loop
if dgl_hist(i)='0' then
cnt0 := cnt0 + 1;
end if;
if dgl_hist(i)='1' then
cnt1 := cnt1 + 1;
end if;
end loop;
if cnt0 >= 3 then
dgl_out <= '0';
elsif cnt1 >= 3 then
dgl_out <= '1';
end if;
-- detect rising edge on pps
pps_last <= dgl_out;
re := (dgl_out='1' and pps_last='0');
-- update counters
if re then
cnt_lsb <= to_unsigned(0, cnt_lsb'length);
lat_lsb <= cnt_lsb;
lat_msb <= lat_msb + 1;
lat_upd <= '1';
else
cnt_lsb <= cnt_lsb + 1;
end if;
-- handle reset
if rst_ref='1' then
dgl_hist <= (others=>'0');
dgl_out <= '0';
pps_last <= '0';
cnt_lsb <= (others=>'0');
lat_upd <= '0';
lat_lsb <= (others=>'0');
lat_msb <= (others=>'0');
end if;
end if;
end process;
-- bring update-pulse into correct clock domain
syn: entity mt_sync_feedback
port map (
i_clk => clk_ref,
i_data => lat_upd,
o_clk => clk_sys,
o_data => out_upd
);
-- output register
process(clk_sys)
begin
if rising_edge(clk_sys) then
-- update output when requested
if out_upd='1' then
out_lsb <= lat_lsb;
out_msb <= lat_msb;
end if;
-- handle reset
if rst_sys='1' then
out_lsb <= (others=>'0');
out_msb <= (others=>'0');
end if;
end if;
end process;
-- output status
status.lsb <= out_lsb;
status.msb <= out_msb;
end rtl;

@ -0,0 +1,72 @@
---------------------------------------------------------------------------------------------------
-- Filename : usbrx_gpio.vhd
-- Project : OsmoSDR FPGA Firmware
-- Purpose : GPIO Block
---------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------
-- Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany --
-- written by Matthias Kleffel --
-- --
-- This program is free software; you can redistribute it and/or modify --
-- it under the terms of the GNU General Public License as published by --
-- the Free Software Foundation as version 3 of the License, or --
-- --
-- This program is distributed in the hope that it will be useful, --
-- but WITHOUT ANY WARRANTY; without even the implied warranty of --
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --
-- GNU General Public License V3 for more details. --
-- --
-- You should have received a copy of the GNU General Public License --
-- along with this program. If not, see <http://www.gnu.org/licenses/>. --
-----------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
library work;
use work.all;
use work.mt_toolbox.all;
use work.usbrx.all;
entity usbrx_gpio is
port(
-- common
clk : in std_logic;
reset : in std_logic;
-- GPIOs
gpio : inout std_logic_vector(10 downto 0);
-- config / status
config : in usbrx_gpio_config_t;
status : out usbrx_gpio_status_t
);
end usbrx_gpio;
architecture rtl of usbrx_gpio is
-- register
signal ireg : std_logic_vector(10 downto 0) := (others=>'0');
signal oreg : std_logic_vector(10 downto 0) := (others=>'0');
signal oena : std_logic_vector(10 downto 0) := (others=>'0');
begin
-- create output-driver
od: for i in gpio'range generate
begin
gpio(i) <= oreg(i) when oena(i)='1' else 'Z';
end generate;
-- IOBs
process(clk)
begin
if rising_edge(clk) then
ireg <= to_X01(gpio);
oreg <= config.odata;
oena <= config.oena;
end if;
end process;
end rtl;

@ -37,15 +37,16 @@ entity usbrx_regbank is
-- config
cfg_pwm : out usbrx_pwm_config_t;
cfg_gpio : out usbrx_gpio_config_t;
cfg_adc : out usbrx_adc_config_t;
cfg_ssc : out usbrx_ssc_config_t;
cfg_fil : out usbrx_fil_config_t;
cfg_off : out usbrx_off_config_t;
-- status (TODO HACK)
adc_i : in unsigned(13 downto 0);
adc_q : in unsigned(13 downto 0);
-- status
stat_ref : in usbrx_ref_status_t;
stat_gpio : in usbrx_gpio_status_t;
-- SPI interface
spi_ncs : in std_logic;
spi_sclk : in std_logic;
@ -71,6 +72,10 @@ architecture rtl of usbrx_regbank is
signal reg_ssc2 : std_logic_vector(7 downto 0);
signal reg_fil : std_logic_vector(2 downto 0);
signal reg_off : std_logic_vector(31 downto 0);
signal reg_gain : std_logic_vector(31 downto 0);
signal reg_swap : std_logic_vector(0 downto 0);
signal reg_ioe : std_logic_vector(10 downto 0);
signal reg_iod : std_logic_vector(10 downto 0);
-- avoid block-ram inference
attribute syn_romstyle : string;
@ -111,6 +116,10 @@ begin
reg_ssc2 <= x"01";
reg_fil <= "011";
reg_off <= x"00000000";
reg_gain <= x"80008000";
reg_swap <= "0";
reg_ioe <= "00000000000";
reg_iod <= "00000000000";
elsif rising_edge(clk) then
-- output zeros by default
bus_rdata <= (others=>'0');
@ -152,9 +161,8 @@ begin
end if;
when 5 =>
-- ADC Quickhack
bus_rdata(15 downto 0) <= to_slv16(adc_i);
bus_rdata(31 downto 16) <= to_slv16(adc_q);
-- <unused>
null;
when 6 =>
-- decimation filter
@ -164,11 +172,44 @@ begin
end if;
when 7 =>
-- offset stage
-- sample offset
bus_rdata <= reg_off;
if bus_wena='1' then
reg_off <= bus_wdata(31 downto 0);
end if;
when 8 =>
-- sample gain
bus_rdata <= reg_gain;
if bus_wena='1' then
reg_gain <= bus_wdata(31 downto 0);
end if;
when 9 =>
-- sample swap
bus_rdata(0 downto 0) <= reg_swap;
if bus_wena='1' then
reg_swap <= bus_wdata( 0 downto 0);
end if;
when 10 =>
-- GPIO - output enable
bus_rdata(10 downto 0) <= reg_ioe;
if bus_wena='1' then
reg_ioe <= bus_wdata(10 downto 0);
end if;
when 11 =>
-- GPIO - output data
bus_rdata(10 downto 0) <= reg_iod;
if bus_wena='1' then
reg_iod <= bus_wdata(10 downto 0);
end if;
when 12 =>
-- GPIO - input data
bus_rdata(10 downto 0) <= stat_gpio.idata;
when 13 =>
-- reference frequency
bus_rdata(24 downto 0) <= std_logic_vector(stat_ref.lsb);
bus_rdata(31 downto 25) <= std_logic_vector(stat_ref.msb);
when others =>
-- invalid address
@ -190,5 +231,10 @@ begin
cfg_fil.decim <= unsigned(reg_fil);
cfg_off.ioff <= signed(reg_off(15 downto 0));
cfg_off.qoff <= signed(reg_off(31 downto 16));
cfg_off.igain <= unsigned(reg_gain(15 downto 0));
cfg_off.qgain <= unsigned(reg_gain(31 downto 16));
cfg_off.swap <= reg_swap(0);
cfg_gpio.oena <= reg_ioe;
cfg_gpio.odata <= reg_iod;
end rtl;

@ -71,6 +71,7 @@ entity usbrx_toplevel is
gps_10k : in std_logic;
-- gpios
led : inout std_logic;
gpio : inout std_logic_vector(9 downto 0);
-- virtual GNDs/VCCs
@ -89,11 +90,16 @@ architecture rtl of usbrx_toplevel is
signal rst_80 : std_logic;
-- config
signal cfg_pwm : usbrx_pwm_config_t;
signal cfg_adc : usbrx_adc_config_t;
signal cfg_ssc : usbrx_ssc_config_t;
signal cfg_fil : usbrx_fil_config_t;
signal cfg_off : usbrx_off_config_t;
signal cfg_pwm : usbrx_pwm_config_t;
signal cfg_gpio : usbrx_gpio_config_t;
signal cfg_adc : usbrx_adc_config_t;
signal cfg_ssc : usbrx_ssc_config_t;
signal cfg_fil : usbrx_fil_config_t;
signal cfg_off : usbrx_off_config_t;
-- status
signal stat_ref : usbrx_ref_status_t;
signal stat_gpio : usbrx_gpio_status_t;
-- ADC <-> offset
signal adc_off_clk : std_logic;
@ -110,22 +116,9 @@ architecture rtl of usbrx_toplevel is
signal fil_out_i : signed(15 downto 0);
signal fil_out_q : signed(15 downto 0);
-- blinken lights
signal blcnt1 : unsigned(31 downto 0) := x"00000000";
signal blcnt2 : unsigned(31 downto 0) := x"00000000";
signal blcnt3 : unsigned(31 downto 0) := x"00000000";
signal blink1 : std_logic := '0';
signal blink2 : std_logic := '0';
signal blink3 : std_logic := '0';
-- enusure that signal-names are kept (important for timing contraints)
attribute syn_keep of clk_in_pclk : signal is true;
-- debug
signal dbg_ext : std_logic;
signal dbg_rst : std_logic;
signal dbg_lock : std_logic;
begin
-- house-keeping
@ -139,12 +132,7 @@ begin
clk_30 => clk_30,
clk_80 => clk_80,
rst_30 => rst_30,
rst_80 => rst_80,
-- debug
dbg_ext => dbg_ext,
dbg_rst => dbg_rst,
dbg_lock => dbg_lock
rst_80 => rst_80
);
-- register bank
@ -160,18 +148,53 @@ begin
cfg_ssc => cfg_ssc,
cfg_fil => cfg_fil,
cfg_off => cfg_off,
-- status (TODO HACK)
adc_i => adc_off_i,
adc_q => adc_off_q,
cfg_gpio => cfg_gpio,
-- status
stat_ref => stat_ref,
stat_gpio => stat_gpio,
-- SPI interface
spi_ncs => ctl_cs,
spi_sclk => ctl_sck,
spi_mosi => ctl_mosi,
spi_miso => ctl_miso
);
-- reference clock measurement
refclk: entity usbrx_clkref
port map (
-- system clocks
clk_sys => clk_80,
rst_sys => rst_80,
-- reference signal
clk_ref => clk_30,
rst_ref => rst_30,
-- 1pps signal
gps_1pps => gps_1pps,
-- status
status => stat_ref
);
-- GPIOs
io: entity usbrx_gpio
port map (
-- common
clk => clk_80,
reset => rst_80,
-- GPIOs
gpio(9 downto 0) => gpio,
gpio(10) => led,
-- config / status
config => cfg_gpio,
status => stat_gpio
);
-- gain PWMs
pwm: entity usbrx_pwm
port map (
@ -273,53 +296,8 @@ begin
ssc_dat => rx_dat
);
-- TODO
-- drive unused IOs
ctl_int <= '1';
-- tx_clk <= '0';
-- blinken lights
process(clk_in_pclk)
begin
if rising_edge(clk_in_pclk) then
if blcnt1=0 then
blcnt1 <= to_unsigned(30000000/2-1, 32);
blink1 <= not blink1;
else
blcnt1 <= blcnt1-1;
end if;
end if;
end process;
process(clk_30)
begin
if rising_edge(clk_30) then
if rst_30='1' then
blcnt2 <= (others=>'0');
blink2 <= '0';
elsif blcnt2=0 then
blcnt2 <= to_unsigned(30000000/2-1, 32);
blink2 <= not blink2;
else
blcnt2 <= blcnt2-1;
end if;
end if;
end process;
process(clk_80)
begin
if rising_edge(clk_80) then
if rst_80='1' then
blcnt3 <= (others=>'0');
blink3 <= '0';
elsif blcnt3=0 then
blcnt3 <= to_unsigned(80000000/2-1, 32);
blink3 <= not blink3;
else
blcnt3 <= blcnt3-1;
end if;
end if;
end process;
-- 8 7 6 5 4 3 2 1
gpio <= "00" & clk_80 & clk_30 & dbg_ext & dbg_rst & dbg_lock & blink3 & blink2 & blink1;
-- virtual GNDs/VCCs
vgnd <= (others=>'0');

@ -47,17 +47,37 @@ package usbrx is
tmode : std_logic;
end record;
-- offset stage
-- offset stage config
type usbrx_off_config_t is record
ioff : signed(15 downto 0);
qoff : signed(15 downto 0);
swap : std_logic;
ioff : signed(15 downto 0);
qoff : signed(15 downto 0);
igain : unsigned(15 downto 0);
qgain : unsigned(15 downto 0);
end record;
-- decimation filter config
type usbrx_fil_config_t is record
decim : unsigned(2 downto 0);
end record;
-- clock reference status
type usbrx_ref_status_t is record
lsb : unsigned(24 downto 0);
msb : unsigned(6 downto 0);
end record;
-- GPIO config
type usbrx_gpio_config_t is record
oena : std_logic_vector(10 downto 0);
odata : std_logic_vector(10 downto 0);
end record;
-- clock reference status
type usbrx_gpio_status_t is record
idata : std_logic_vector(10 downto 0);
end record;
end usbrx;
package body usbrx is

@ -1,6 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<XML>
<document type="stimulators" version="1">
<set name="ASDB Stimulators" active="1"/>
<set name="ASDB Stimulators" active="1">
<stimulator>
<signal_path value="/tb_usbrx/uut/off/config.igain"/>
<rawdescription value="VAL:FRM:Override:x&quot;9000&quot;:&lt;= x&quot;9000&quot;:1:"/>
</stimulator>
<stimulator>
<signal_path value="/tb_usbrx/uut/off/in_i"/>
<rawdescription value="VAL:FRM:Override:10#4000:&lt;= 10#4000:0:"/>
</stimulator>
</set>
</document>
</XML>

@ -1 +1,2 @@
i<>.\src\usbrx\toplevel\usbrx_toplevel.vhd
i<>.\src\mt_toolbox\mt_synctools.vhd

@ -24,7 +24,7 @@ LANGUAGE=VHDL
REFRESH_FLOW=1
FAMILY=Lattice XP2
fileopeninsrc=1
fileopenfolder=C:\
fileopenfolder=C:\DVB\sr_systems\sr-usbrx\osmo-sdr\fpga\hw-v2\src\mt_toolbox
IMPL_TOOL=
SYNTH_TOOL=
NoWarningsSDF=0
@ -108,6 +108,7 @@ testbench=1
[Files]
mt_toolbox/mt_toolbox.vhd=-1
mt_toolbox/mt_clktools.vhd=-1
mt_toolbox/mt_synctools.vhd=-1
mt_filter/mt_filter.vhd=-1
mt_filter/mt_fil_storage_slow.vhd=-1
mt_filter/mt_fil_mac_slow.vhd=-1
@ -119,6 +120,8 @@ usbrx\datapath/usbrx_offset.vhd=-1
usbrx\datapath/usbrx_decimate.vhd=-1
usbrx\datapath/usbrx_ssc.vhd=-1
usbrx\toplevel/usbrx_clkgen.vhd=-1
usbrx\toplevel/usbrx_clkref.vhd=-1
usbrx\toplevel/usbrx_gpio.vhd=-1
usbrx\toplevel/usbrx_spi.vhd=-1
usbrx\toplevel/usbrx_regbank.vhd=-1
usbrx\toplevel/usbrx_pwm.vhd=-1
@ -129,6 +132,7 @@ testbench/tb_usbrx.vhd=-1
[Files.Data]
.\src\mt_toolbox\mt_toolbox.vhd=VHDL Source Code
.\src\mt_toolbox\mt_clktools.vhd=VHDL Source Code
.\src\mt_toolbox\mt_synctools.vhd=VHDL Source Code
.\src\mt_filter\mt_filter.vhd=VHDL Source Code
.\src\mt_filter\mt_fil_storage_slow.vhd=VHDL Source Code
.\src\mt_filter\mt_fil_mac_slow.vhd=VHDL Source Code
@ -140,6 +144,8 @@ testbench/tb_usbrx.vhd=-1
.\src\usbrx\datapath\usbrx_decimate.vhd=VHDL Source Code
.\src\usbrx\datapath\usbrx_ssc.vhd=VHDL Source Code
.\src\usbrx\toplevel\usbrx_clkgen.vhd=VHDL Source Code
.\src\usbrx\toplevel\usbrx_clkref.vhd=VHDL Source Code
.\src\usbrx\toplevel\usbrx_gpio.vhd=VHDL Source Code
.\src\usbrx\toplevel\usbrx_spi.vhd=VHDL Source Code
.\src\usbrx\toplevel\usbrx_regbank.vhd=VHDL Source Code
.\src\usbrx\toplevel\usbrx_pwm.vhd=VHDL Source Code

@ -1,63 +0,0 @@
[General]
CurrentVersion=103
[COMPILESTATUS|.\src\mt_toolbox\mt_toolbox.vhd]
FileTimeLow=30225029
Status=Compiled
[COMPILESTATUS|.\src\mt_toolbox\mt_clktools.vhd]
FileTimeLow=30225029
Status=Compiled
[COMPILESTATUS|.\src\mt_filter\mt_filter.vhd]
FileTimeLow=30225028
Status=Compiled
[COMPILESTATUS|.\src\mt_filter\mt_fil_storage_slow.vhd]
FileTimeLow=30225028
Status=Compiled
[COMPILESTATUS|.\src\mt_filter\mt_fil_mac_slow.vhd]
FileTimeLow=30222064
Status=Compiled
[COMPILESTATUS|.\src\mt_filter\mt_fir_symmetric_slow.vhd]
FileTimeLow=30225032
Status=Compiled
[COMPILESTATUS|.\src\usbrx\usbrx.vhd]
FileTimeLow=30225029
Status=Compiled
[COMPILESTATUS|.\src\usbrx\filter\usbrx_halfband.vhd]
FileTimeLow=30225030
Status=Compiled
[COMPILESTATUS|.\src\usbrx\datapath\usbrx_ad7357.vhd]
FileTimeLow=30225030
Status=Compiled
[COMPILESTATUS|.\src\usbrx\datapath\usbrx_offset.vhd]
FileTimeLow=30225030
Status=Compiled
[COMPILESTATUS|.\src\usbrx\datapath\usbrx_decimate.vhd]
FileTimeLow=30225031
Status=Compiled
[COMPILESTATUS|.\src\usbrx\datapath\usbrx_ssc.vhd]
FileTimeLow=30225031
Status=Compiled
[COMPILESTATUS|.\src\usbrx\toplevel\usbrx_clkgen.vhd]
FileTimeLow=30225031
Status=Compiled
[COMPILESTATUS|.\src\usbrx\toplevel\usbrx_spi.vhd]
FileTimeLow=30225031
Status=Compiled
[COMPILESTATUS|.\src\usbrx\toplevel\usbrx_regbank.vhd]
FileTimeLow=30225031
Status=Compiled
[COMPILESTATUS|.\src\usbrx\toplevel\usbrx_pwm.vhd]
FileTimeLow=30225031
Status=Compiled
[COMPILESTATUS|.\src\usbrx\toplevel\usbrx_toplevel.vhd]
FileTimeLow=30225031
Status=Compiled
[COMPILESTATUS|.\src\testbench\tb_filter.vhd]
FileTimeLow=30225031
Status=Compiled
[COMPILESTATUS|.\src\testbench\tb_usbrx.vhd]
FileTimeLow=30225031
Status=Compiled
[CACHEDOC|Aldec.Project.Generic.7|.\usbrx_vhdl.adf|]
Path=
[Gui config]
RunFor=100 ns