summaryrefslogtreecommitdiffstats
path: root/fpga/hw-v2/src/usbrx/toplevel/usbrx_regbank.vhd
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/hw-v2/src/usbrx/toplevel/usbrx_regbank.vhd')
-rw-r--r--fpga/hw-v2/src/usbrx/toplevel/usbrx_regbank.vhd194
1 files changed, 194 insertions, 0 deletions
diff --git a/fpga/hw-v2/src/usbrx/toplevel/usbrx_regbank.vhd b/fpga/hw-v2/src/usbrx/toplevel/usbrx_regbank.vhd
new file mode 100644
index 0000000..feb4bd8
--- /dev/null
+++ b/fpga/hw-v2/src/usbrx/toplevel/usbrx_regbank.vhd
@@ -0,0 +1,194 @@
+---------------------------------------------------------------------------------------------------
+-- Filename : usbrx_regbank.vhd
+-- Project : OsmoSDR FPGA Firmware
+-- Purpose : Registerbank
+---------------------------------------------------------------------------------------------------
+
+-----------------------------------------------------------------------------------
+-- 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_regbank is
+ port(
+ -- common
+ clk : in std_logic;
+ reset : in std_logic;
+
+ -- config
+ cfg_pwm : out usbrx_pwm_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);
+
+ -- SPI interface
+ spi_ncs : in std_logic;
+ spi_sclk : in std_logic;
+ spi_mosi : in std_logic;
+ spi_miso : out std_logic
+ );
+end usbrx_regbank;
+
+architecture rtl of usbrx_regbank is
+
+ -- bus interface
+ signal bus_rena : std_logic;
+ signal bus_wena : std_logic;
+ signal bus_addr : unsigned(6 downto 0);
+ signal bus_rdata : std_logic_vector(31 downto 0);
+ signal bus_wdata : std_logic_vector(31 downto 0);
+
+ -- registers
+ signal reg_pwm1 : std_logic_vector(31 downto 0);
+ signal reg_pwm2 : std_logic_vector(31 downto 0);
+ signal reg_adc : std_logic_vector(15 downto 0);
+ signal reg_ssc1 : std_logic_vector(0 downto 0);
+ 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);
+
+ -- avoid block-ram inference
+ attribute syn_romstyle : string;
+ attribute syn_romstyle of rtl : architecture is "logic";
+
+begin
+
+ -- SPI slave
+ spi: entity usbrx_spi
+ port map (
+ -- common
+ clk => clk,
+ reset => reset,
+
+ -- SPI interface
+ spi_ncs => spi_ncs,
+ spi_sclk => spi_sclk,
+ spi_mosi => spi_mosi,
+ spi_miso => spi_miso,
+
+ -- bus interface
+ bus_rena => bus_rena,
+ bus_wena => bus_wena,
+ bus_addr => bus_addr,
+ bus_rdata => bus_rdata,
+ bus_wdata => bus_wdata
+ );
+
+ -- handle requests
+ process(reset, clk)
+ begin
+ if reset = '1' then
+ bus_rdata <= (others=>'0');
+ reg_pwm1 <= x"17701F3F";
+ reg_pwm2 <= x"07D01F3F";
+ reg_adc <= x"0401";
+ reg_ssc1 <= "0";
+ reg_ssc2 <= x"01";
+ reg_fil <= "011";
+ reg_off <= x"00000000";
+ elsif rising_edge(clk) then
+ -- output zeros by default
+ bus_rdata <= (others=>'0');
+
+ -- handle requests
+ case to_integer(bus_addr) is
+ when 0 =>
+ -- identification
+ bus_rdata <= x"DEADBEEF";
+
+ when 1 =>
+ -- PWM #1
+ bus_rdata <= reg_pwm1;
+ if bus_wena='1' then
+ reg_pwm1 <= bus_wdata(31 downto 0);
+ end if;
+
+ when 2 =>
+ -- PWM #2
+ bus_rdata <= reg_pwm2;
+ if bus_wena='1' then
+ reg_pwm2 <= bus_wdata(31 downto 0);
+ end if;
+
+ when 3 =>
+ -- ADC interface
+ bus_rdata <= to_slv32(reg_adc);
+ if bus_wena='1' then
+ reg_adc <= bus_wdata(15 downto 0);
+ end if;
+
+ when 4 =>
+ -- SSC interface
+ bus_rdata( 0 downto 0) <= reg_ssc1;
+ bus_rdata(15 downto 8) <= reg_ssc2;
+ if bus_wena='1' then
+ reg_ssc1 <= bus_wdata( 0 downto 0);
+ reg_ssc2 <= bus_wdata(15 downto 8);
+ end if;
+
+ when 5 =>
+ -- ADC Quickhack
+ bus_rdata(15 downto 0) <= to_slv16(adc_i);
+ bus_rdata(31 downto 16) <= to_slv16(adc_q);
+
+ when 6 =>
+ -- decimation filter
+ bus_rdata <= to_slv32(reg_fil);
+ if bus_wena='1' then
+ reg_fil <= bus_wdata(2 downto 0);
+ end if;
+
+ when 7 =>
+ -- offset stage
+ bus_rdata <= reg_off;
+ if bus_wena='1' then
+ reg_off <= bus_wdata(31 downto 0);
+ end if;
+
+ when others =>
+ -- invalid address
+ null;
+ end case;
+ end if;
+ end process;
+
+ -- map registers to config
+ cfg_pwm.freq0 <= unsigned(reg_pwm1(15 downto 0));
+ cfg_pwm.freq1 <= unsigned(reg_pwm2(15 downto 0));
+ cfg_pwm.duty0 <= unsigned(reg_pwm1(31 downto 16));
+ cfg_pwm.duty1 <= unsigned(reg_pwm2(31 downto 16));
+ cfg_adc.clkdiv <= unsigned(reg_adc( 7 downto 0));
+ cfg_adc.acqlen <= unsigned(reg_adc(15 downto 8));
+ cfg_ssc.tmode <= reg_ssc1(0);
+ cfg_ssc.clkdiv <= unsigned(reg_ssc2);
+ cfg_fil.decim <= unsigned(reg_fil);
+ cfg_fil.decim <= unsigned(reg_fil);
+ cfg_off.ioff <= signed(reg_off(15 downto 0));
+ cfg_off.qoff <= signed(reg_off(31 downto 16));
+
+end rtl;