summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Daniel <cd@maintech.de>2012-05-30 22:28:38 +0200
committerChristian Daniel <cd@maintech.de>2012-05-30 22:28:38 +0200
commit83340d0b371fa5693270871f077d31a910d4af72 (patch)
tree639f1dd36c545852a8c19f8dfe6730f26417b5b0
parent1c329c81654ee9540650c1bd933732ce83feec04 (diff)
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
-rw-r--r--fpga/hw-v2/compilation.order3
-rw-r--r--fpga/hw-v2/compile.cfg6
-rw-r--r--fpga/hw-v2/deploy/usbrx_data.vmebin134040 -> 133639 bytes
-rw-r--r--fpga/hw-v2/deploy/usbrx_fpga_regs.odtbin0 -> 92065 bytes
-rw-r--r--fpga/hw-v2/deploy/usbrx_fpga_regs.pdfbin158377 -> 172475 bytes
-rw-r--r--fpga/hw-v2/diamond/usbrx_vhdl.ldf12
-rw-r--r--fpga/hw-v2/diamond/usbrx_vhdl.lpf4
-rw-r--r--fpga/hw-v2/src/mt_toolbox/mt_clktools.vhd12
-rw-r--r--fpga/hw-v2/src/mt_toolbox/mt_synctools.vhd135
-rw-r--r--fpga/hw-v2/src/mt_toolbox/mt_toolbox.vhd7
-rw-r--r--fpga/hw-v2/src/testbench/tb_usbrx.vhd22
-rw-r--r--fpga/hw-v2/src/usbrx/datapath/usbrx_offset.vhd47
-rw-r--r--fpga/hw-v2/src/usbrx/toplevel/usbrx_clkgen.vhd15
-rw-r--r--fpga/hw-v2/src/usbrx/toplevel/usbrx_clkref.vhd158
-rw-r--r--fpga/hw-v2/src/usbrx/toplevel/usbrx_gpio.vhd72
-rw-r--r--fpga/hw-v2/src/usbrx/toplevel/usbrx_regbank.vhd62
-rw-r--r--fpga/hw-v2/src/usbrx/toplevel/usbrx_toplevel.vhd128
-rw-r--r--fpga/hw-v2/src/usbrx/usbrx.vhd26
-rw-r--r--fpga/hw-v2/stimulators.set11
-rw-r--r--fpga/hw-v2/synthesis.order1
-rw-r--r--fpga/hw-v2/usbrx_vhdl.adf8
-rw-r--r--fpga/hw-v2/usbrx_vhdl.wsp63
22 files changed, 596 insertions, 196 deletions
diff --git a/fpga/hw-v2/compilation.order b/fpga/hw-v2/compilation.order
index 69068cb..ac3404e 100644
--- a/fpga/hw-v2/compilation.order
+++ b/fpga/hw-v2/compilation.order
@@ -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
diff --git a/fpga/hw-v2/compile.cfg b/fpga/hw-v2/compile.cfg
index 410fac9..7030cb9 100644
--- a/fpga/hw-v2/compile.cfg
+++ b/fpga/hw-v2/compile.cfg
@@ -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
diff --git a/fpga/hw-v2/deploy/usbrx_data.vme b/fpga/hw-v2/deploy/usbrx_data.vme
index c3488fb..b4a5261 100644
--- a/fpga/hw-v2/deploy/usbrx_data.vme
+++ b/fpga/hw-v2/deploy/usbrx_data.vme
Binary files differ
diff --git a/fpga/hw-v2/deploy/usbrx_fpga_regs.odt b/fpga/hw-v2/deploy/usbrx_fpga_regs.odt
new file mode 100644
index 0000000..6ce65d0
--- /dev/null
+++ b/fpga/hw-v2/deploy/usbrx_fpga_regs.odt
Binary files differ
diff --git a/fpga/hw-v2/deploy/usbrx_fpga_regs.pdf b/fpga/hw-v2/deploy/usbrx_fpga_regs.pdf
index 4aa942c..b90d6dc 100644
--- a/fpga/hw-v2/deploy/usbrx_fpga_regs.pdf
+++ b/fpga/hw-v2/deploy/usbrx_fpga_regs.pdf
Binary files differ
diff --git a/fpga/hw-v2/diamond/usbrx_vhdl.ldf b/fpga/hw-v2/diamond/usbrx_vhdl.ldf
index cdf9ed2..27207b7 100644
--- a/fpga/hw-v2/diamond/usbrx_vhdl.ldf
+++ b/fpga/hw-v2/diamond/usbrx_vhdl.ldf
@@ -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>
diff --git a/fpga/hw-v2/diamond/usbrx_vhdl.lpf b/fpga/hw-v2/diamond/usbrx_vhdl.lpf
index d997a99..3f9f15b 100644
--- a/fpga/hw-v2/diamond/usbrx_vhdl.lpf
+++ b/fpga/hw-v2/diamond/usbrx_vhdl.lpf
@@ -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 ;
diff --git a/fpga/hw-v2/src/mt_toolbox/mt_clktools.vhd b/fpga/hw-v2/src/mt_toolbox/mt_clktools.vhd
index b0f3e73..1a1d47e 100644
--- a/fpga/hw-v2/src/mt_toolbox/mt_clktools.vhd
+++ b/fpga/hw-v2/src/mt_toolbox/mt_clktools.vhd
@@ -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;
diff --git a/fpga/hw-v2/src/mt_toolbox/mt_synctools.vhd b/fpga/hw-v2/src/mt_toolbox/mt_synctools.vhd
new file mode 100644
index 0000000..722eaca
--- /dev/null
+++ b/fpga/hw-v2/src/mt_toolbox/mt_synctools.vhd
@@ -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;
diff --git a/fpga/hw-v2/src/mt_toolbox/mt_toolbox.vhd b/fpga/hw-v2/src/mt_toolbox/mt_toolbox.vhd
index 77768a5..ab3a2fe 100644
--- a/fpga/hw-v2/src/mt_toolbox/mt_toolbox.vhd
+++ b/fpga/hw-v2/src/mt_toolbox/mt_toolbox.vhd
@@ -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;
diff --git a/fpga/hw-v2/src/testbench/tb_usbrx.vhd b/fpga/hw-v2/src/testbench/tb_usbrx.vhd
index 4884ee7..2412c65 100644
--- a/fpga/hw-v2/src/testbench/tb_usbrx.vhd
+++ b/fpga/hw-v2/src/testbench/tb_usbrx.vhd
@@ -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";
diff --git a/fpga/hw-v2/src/usbrx/datapath/usbrx_offset.vhd b/fpga/hw-v2/src/usbrx/datapath/usbrx_offset.vhd
index 8337256..42ba8fc 100644
--- a/fpga/hw-v2/src/usbrx/datapath/usbrx_offset.vhd
+++ b/fpga/hw-v2/src/usbrx/datapath/usbrx_offset.vhd
@@ -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
diff --git a/fpga/hw-v2/src/usbrx/toplevel/usbrx_clkgen.vhd b/fpga/hw-v2/src/usbrx/toplevel/usbrx_clkgen.vhd
index 382cd78..b1fc9a8 100644
--- a/fpga/hw-v2/src/usbrx/toplevel/usbrx_clkgen.vhd
+++ b/fpga/hw-v2/src/usbrx/toplevel/usbrx_clkgen.vhd
@@ -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
diff --git a/fpga/hw-v2/src/usbrx/toplevel/usbrx_clkref.vhd b/fpga/hw-v2/src/usbrx/toplevel/usbrx_clkref.vhd
new file mode 100644
index 0000000..0149a07
--- /dev/null
+++ b/fpga/hw-v2/src/usbrx/toplevel/usbrx_clkref.vhd
@@ -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;
diff --git a/fpga/hw-v2/src/usbrx/toplevel/usbrx_gpio.vhd b/fpga/hw-v2/src/usbrx/toplevel/usbrx_gpio.vhd
new file mode 100644
index 0000000..5c62fe5
--- /dev/null
+++ b/fpga/hw-v2/src/usbrx/toplevel/usbrx_gpio.vhd
@@ -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;
diff --git a/fpga/hw-v2/src/usbrx/toplevel/usbrx_regbank.vhd b/fpga/hw-v2/src/usbrx/toplevel/usbrx_regbank.vhd
index feb4bd8..fb92e52 100644
--- a/fpga/hw-v2/src/usbrx/toplevel/usbrx_regbank.vhd
+++ b/fpga/hw-v2/src/usbrx/toplevel/usbrx_regbank.vhd
@@ -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;
diff --git a/fpga/hw-v2/src/usbrx/toplevel/usbrx_toplevel.vhd b/fpga/hw-v2/src/usbrx/toplevel/usbrx_toplevel.vhd
index b0b9010..98a0384 100644
--- a/fpga/hw-v2/src/usbrx/toplevel/usbrx_toplevel.vhd
+++ b/fpga/hw-v2/src/usbrx/toplevel/usbrx_toplevel.vhd
@@ -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');
diff --git a/fpga/hw-v2/src/usbrx/usbrx.vhd b/fpga/hw-v2/src/usbrx/usbrx.vhd
index 59d4f11..3839c7a 100644
--- a/fpga/hw-v2/src/usbrx/usbrx.vhd
+++ b/fpga/hw-v2/src/usbrx/usbrx.vhd
@@ -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
diff --git a/fpga/hw-v2/stimulators.set b/fpga/hw-v2/stimulators.set
index 78296b7..01ec171 100644
--- a/fpga/hw-v2/stimulators.set
+++ b/fpga/hw-v2/stimulators.set
@@ -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>
diff --git a/fpga/hw-v2/synthesis.order b/fpga/hw-v2/synthesis.order
index 747b5f6..7d0a9d0 100644
--- a/fpga/hw-v2/synthesis.order
+++ b/fpga/hw-v2/synthesis.order
@@ -1 +1,2 @@
i<>.\src\usbrx\toplevel\usbrx_toplevel.vhd
+i<>.\src\mt_toolbox\mt_synctools.vhd
diff --git a/fpga/hw-v2/usbrx_vhdl.adf b/fpga/hw-v2/usbrx_vhdl.adf
index a1257ce..325fe97 100644
--- a/fpga/hw-v2/usbrx_vhdl.adf
+++ b/fpga/hw-v2/usbrx_vhdl.adf
@@ -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
diff --git a/fpga/hw-v2/usbrx_vhdl.wsp b/fpga/hw-v2/usbrx_vhdl.wsp
deleted file mode 100644
index af46466..0000000
--- a/fpga/hw-v2/usbrx_vhdl.wsp
+++ /dev/null
@@ -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