Commit fa9ea901 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

softpll-ng: initial commit

parents
files = ["spll_period_detect.vhd",
"spll_wbgen2_pkg.vhd",
# "wr_softpll_ng.vhd",
# "xwr_softpll_ng.vhd",
"spll_wb_slave.vhd"]
\ No newline at end of file
#!/bin/bash
wbgen2 -C softpll_regs.h -V spll_wb_slave.vhd -K ../../sim/softpll_regs_ng.vh -C softpll_regs.h --hstyle record -p spll_wbgen2_pkg.vhd spll_wb_slave.wb
\ No newline at end of file
-------------------------------------------------------------------------------
-- Title : SoftPLL - linear frequency/period detector.
-- Project : White Rabbit
-------------------------------------------------------------------------------
-- File : softpll_period_detect.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN BE-Co-HT
-- Created : 2010-06-14
-- Last update: 2012-01-17
-- Platform : FPGA-generic
-- Standard : VHDL'87
-------------------------------------------------------------------------------
-- Description: Simple linear frequency detector with programmable error
-- setpoint and gating period. The measured clocks are: clk_ref_i and clk_fbck_i.
-- The error value is outputted every 2^(hpll_fbcr_fd_gate_i + 14) cycles on a
-- freq_err_o. A pulse is produced on freq_err_stb_p_o every time freq_err_o
-- is updated with a new value. freq_err_o value is:
-- - positive when clk_fbck_i is slower than selected frequency setpoint
-- - negative when clk_fbck_i is faster than selected frequency setpoint
-------------------------------------------------------------------------------
-- Copyright (c) 2010 Tomasz Wlostowski
-------------------------------------------------------------------------------
-- Revisions :
-- Date Version Author Description
-- 2010-06-14 1.0 twlostow Created
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.gencores_pkg.all;
entity spll_period_detect is
generic(
g_num_ref_inputs : integer := 6);
port (
-------------------------------------------------------------------------------
-- Clocks & resets
-------------------------------------------------------------------------------
-- reference clocks
clk_ref_i : in std_logic_vector(g_num_ref_inputs-1 downto 0);
-- fed-back (VCO) clock
clk_dmtd_i : in std_logic;
-- system clock (wishbone and I/O)
clk_sys_i : in std_logic;
-- reset signals (the same reset synced to different clocks)
rst_n_dmtdclk_i : in std_logic;
rst_n_sysclk_i : in std_logic;
-------------------------------------------------------------------------------
-- Outputs
-------------------------------------------------------------------------------
-- frequency error value (signed)
freq_err_o : out std_logic_vector(11 downto 0);
-- frequency error valid pulse
freq_err_stb_p_o : out std_logic;
in_sel_i : in std_logic_vector(4 downto 0)
);
end spll_period_detect;
architecture rtl of spll_period_detect is
constant c_COUNTER_BITS : integer := 19;
constant c_GATING_PERIOD : integer := 1024;
-- frequency counters: feedback clock & gating counter
signal in_muxed : std_logic;
signal in_sel_onehot : std_logic_vector(g_num_ref_inputs-1 downto 0);
signal freq : std_logic_vector(19 downto 0);
signal freq_valid_dmtdclk, freq_valid_sysclk : std_logic;
signal freq_valid_dmtdclk_d0, freq_valid_dmtdclk_pulse : std_logic;
begin -- rtl
gen_in_sel_mask : for i in 0 to g_num_ref_inputs-1 generate
in_sel_onehot(i) <= '1' when i = to_integer(unsigned(in_sel_i)) else '0';
end generate gen_in_sel_mask; -- i
in_muxed <= '1' when unsigned(in_sel_onehot and clk_ref_i) /= 0 else '0';
U_Freq_Meter : gc_frequency_meter
generic map (
g_with_internal_timebase => true,
g_clk_sys_freq => c_GATING_PERIOD,
g_counter_bits => 20)
port map (
clk_sys_i => clk_dmtd_i,
clk_in_i => in_muxed,
rst_n_i => rst_n_dmtdclk_i,
pps_p1_i => '0',
freq_o => freq,
freq_valid_o => freq_valid_dmtdclk);
U_Pulse_Sync : gc_pulse_synchronizer
port map (
clk_in_i => clk_dmtd_i,
clk_out_i => clk_sys_i,
rst_n_i => rst_n_sysclk_i,
d_p_i => freq_valid_dmtdclk_pulse,
q_p_o => freq_valid_sysclk);
p_edge_detect: process(clk_dmtd_i)
begin
if rising_edge(clk_dmtd_i) then
freq_valid_dmtdclk_d0 <= freq_valid_dmtdclk;
end if;
end process;
freq_valid_dmtdclk_pulse <= freq_valid_dmtdclk and not freq_valid_dmtdclk_d0;
p_output : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_n_sysclk_i = '0' then
freq_err_o <= (others => '0');
freq_err_stb_p_o <= '0';
elsif(freq_valid_sysclk = '1') then
freq_err_o <= std_logic_vector(resize(unsigned(freq) - c_GATING_PERIOD, freq_err_o'length));
freq_err_stb_p_o <= '1';
else
freq_err_stb_p_o <= '0';
end if;
end if;
end process;
end rtl;
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for WR Softcore PLL
---------------------------------------------------------------------------------------
-- File : spll_wb_slave.vhd
-- Author : auto-generated by wbgen2 from wr_softpll.wb
-- Created : Wed Jan 18 13:13:08 2012
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wr_softpll.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wbgen2_pkg.all;
use work.SPLL_wbgen2_pkg.all;
entity spll_wb_slave is
port (
rst_n_i : in std_logic;
wb_clk_i : in std_logic;
wb_addr_i : in std_logic_vector(3 downto 0);
wb_data_i : in std_logic_vector(31 downto 0);
wb_data_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_irq_o : out std_logic;
tag_hpll_rd_period_o : out std_logic;
irq_tag_i : in std_logic;
regs_i : in t_SPLL_in_registers;
regs_o : out t_SPLL_out_registers
);
end spll_wb_slave;
architecture syn of spll_wb_slave is
signal spll_csr_per_sel_int : std_logic_vector(5 downto 0);
signal spll_occr_out_lock_int : std_logic_vector(7 downto 0);
signal spll_deglitch_thr_int : std_logic_vector(15 downto 0);
signal spll_trr_in_int : std_logic_vector(31 downto 0);
signal spll_trr_out_int : std_logic_vector(31 downto 0);
signal spll_trr_rdreq_int : std_logic ;
signal spll_trr_rdreq_int_d0 : std_logic ;
signal eic_idr_int : std_logic_vector(0 downto 0);
signal eic_idr_write_int : std_logic ;
signal eic_ier_int : std_logic_vector(0 downto 0);
signal eic_ier_write_int : std_logic ;
signal eic_imr_int : std_logic_vector(0 downto 0);
signal eic_isr_clear_int : std_logic_vector(0 downto 0);
signal eic_isr_status_int : std_logic_vector(0 downto 0);
signal eic_irq_ack_int : std_logic_vector(0 downto 0);
signal eic_isr_write_int : std_logic ;
signal spll_trr_empty_int : std_logic ;
signal irq_inputs_vector_int : std_logic_vector(0 downto 0);
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(3 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal bus_clock_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
wrdata_reg <= wb_data_i;
bwsel_reg <= wb_sel_i;
bus_clock_int <= wb_clk_i;
rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
allones <= (others => '1');
allzeros <= (others => '0');
--
-- Main register bank access process.
process (bus_clock_int, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
spll_csr_per_sel_int <= "000000";
spll_occr_out_lock_int <= "00000000";
regs_o.spll_rcer_load_o <= '0';
regs_o.spll_ocer_load_o <= '0';
tag_hpll_rd_period_o <= '0';
regs_o.spll_dac_hpll_wr_o <= '0';
regs_o.spll_dac_main_value_wr_o <= '0';
regs_o.spll_dac_main_dac_sel_wr_o <= '0';
spll_deglitch_thr_int <= "0000000000000000";
eic_idr_write_int <= '0';
eic_ier_write_int <= '0';
eic_isr_write_int <= '0';
spll_trr_rdreq_int <= '0';
elsif rising_edge(bus_clock_int) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
regs_o.spll_rcer_load_o <= '0';
regs_o.spll_ocer_load_o <= '0';
tag_hpll_rd_period_o <= '0';
regs_o.spll_dac_hpll_wr_o <= '0';
regs_o.spll_dac_main_value_wr_o <= '0';
regs_o.spll_dac_main_dac_sel_wr_o <= '0';
eic_idr_write_int <= '0';
eic_ier_write_int <= '0';
eic_isr_write_int <= '0';
ack_in_progress <= '0';
else
regs_o.spll_rcer_load_o <= '0';
regs_o.spll_ocer_load_o <= '0';
regs_o.spll_dac_hpll_wr_o <= '0';
regs_o.spll_dac_main_value_wr_o <= '0';
regs_o.spll_dac_main_dac_sel_wr_o <= '0';
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(3 downto 0) is
when "0000" =>
if (wb_we_i = '1') then
spll_csr_per_sel_int <= wrdata_reg(5 downto 0);
else
rddata_reg(5 downto 0) <= spll_csr_per_sel_int;
rddata_reg(13 downto 8) <= regs_i.spll_csr_n_ref_i;
rddata_reg(18 downto 16) <= regs_i.spll_csr_n_out_i;
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "0001" =>
if (wb_we_i = '1') then
spll_occr_out_lock_int <= wrdata_reg(15 downto 8);
else
rddata_reg(7 downto 0) <= regs_i.spll_occr_out_en_i;
rddata_reg(15 downto 8) <= spll_occr_out_lock_int;
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "0010" =>
if (wb_we_i = '1') then
regs_o.spll_rcer_load_o <= '1';
else
rddata_reg(31 downto 0) <= regs_i.spll_rcer_i;
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "0011" =>
if (wb_we_i = '1') then
regs_o.spll_ocer_load_o <= '1';
else
rddata_reg(7 downto 0) <= regs_i.spll_ocer_i;
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "0100" =>
if (wb_we_i = '1') then
rddata_reg(16) <= 'X';
else
rddata_reg(15 downto 0) <= regs_i.spll_per_hpll_error_i;
tag_hpll_rd_period_o <= '1';
rddata_reg(16) <= regs_i.spll_per_hpll_valid_i;
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "0101" =>
if (wb_we_i = '1') then
regs_o.spll_dac_hpll_wr_o <= '1';
else
rddata_reg(0) <= 'X';
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "0110" =>
if (wb_we_i = '1') then
regs_o.spll_dac_main_value_wr_o <= '1';
regs_o.spll_dac_main_dac_sel_wr_o <= '1';
else
rddata_reg(0) <= 'X';
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "0111" =>
if (wb_we_i = '1') then
spll_deglitch_thr_int <= wrdata_reg(15 downto 0);
else
rddata_reg(15 downto 0) <= spll_deglitch_thr_int;
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "1000" =>
if (wb_we_i = '1') then
eic_idr_write_int <= '1';
else
rddata_reg(0) <= 'X';
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "1001" =>
if (wb_we_i = '1') then
eic_ier_write_int <= '1';
else
rddata_reg(0) <= 'X';
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "1010" =>
if (wb_we_i = '1') then
else
rddata_reg(0) <= eic_imr_int(0);
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "1011" =>
if (wb_we_i = '1') then
eic_isr_write_int <= '1';
else
rddata_reg(0) <= eic_isr_status_int(0);
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "1100" =>
if (wb_we_i = '1') then
else
if (spll_trr_rdreq_int_d0 = '0') then
spll_trr_rdreq_int <= not spll_trr_rdreq_int;
else
rddata_reg(23 downto 0) <= spll_trr_out_int(23 downto 0);
rddata_reg(30 downto 24) <= spll_trr_out_int(30 downto 24);
rddata_reg(31) <= spll_trr_out_int(31);
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end if;
end if;
when "1101" =>
if (wb_we_i = '1') then
else
rddata_reg(17) <= spll_trr_empty_int;
rddata_reg(0) <= 'X';
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
end if;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
wb_data_o <= rddata_reg;
-- Period detector reference select
regs_o.spll_csr_per_sel_o <= spll_csr_per_sel_int;
-- Number of reference channels (max: 32)
-- Number of output channels (max: 8)
-- Output Channel HW enable flag
-- Output Channel locked flag
regs_o.spll_occr_out_lock_o <= spll_occr_out_lock_int;
-- Reference Channel Enable
regs_o.spll_rcer_o <= wrdata_reg(31 downto 0);
-- Output Channel Enable
regs_o.spll_ocer_o <= wrdata_reg(7 downto 0);
-- Period error value
-- Period Error Valid
-- DAC value
-- pass-through field: DAC value in register: Helper DAC Output
regs_o.spll_dac_hpll_o <= wrdata_reg(15 downto 0);
-- DAC value
-- pass-through field: DAC value in register: Main DAC Output
regs_o.spll_dac_main_value_o <= wrdata_reg(15 downto 0);
-- DAC select
-- pass-through field: DAC select in register: Main DAC Output
regs_o.spll_dac_main_dac_sel_o <= wrdata_reg(19 downto 16);
-- Threshold
regs_o.spll_deglitch_thr_o <= spll_deglitch_thr_int;
-- extra code for reg/fifo/mem: Tag Readout Register
spll_trr_in_int(23 downto 0) <= regs_i.spll_trr_value_i;
spll_trr_in_int(30 downto 24) <= regs_i.spll_trr_chan_id_i;
spll_trr_in_int(31) <= regs_i.spll_trr_disc_i;
spll_trr_INST : wbgen2_fifo_sync
generic map (
g_size => 32,
g_width => 32,
g_usedw_size => 5
)
port map (
wr_req_i => regs_i.spll_trr_wr_req_i,
wr_full_o => regs_o.spll_trr_wr_full_o,
rd_full_o => open,
rd_empty_o => spll_trr_empty_int,
rd_usedw_o => open,
rd_req_i => spll_trr_rdreq_int,
clk_i => bus_clock_int,
wr_data_i => spll_trr_in_int,
rd_data_o => spll_trr_out_int
);
-- extra code for reg/fifo/mem: Interrupt disable register
eic_idr_int(0) <= wrdata_reg(0);
-- extra code for reg/fifo/mem: Interrupt enable register
eic_ier_int(0) <= wrdata_reg(0);
-- extra code for reg/fifo/mem: Interrupt status register
eic_isr_clear_int(0) <= wrdata_reg(0);
-- extra code for reg/fifo/mem: IRQ_CONTROLLER
eic_irq_controller_inst : wbgen2_eic
generic map (
g_num_interrupts => 1,
g_irq00_mode => 3,
g_irq01_mode => 0,
g_irq02_mode => 0,
g_irq03_mode => 0,
g_irq04_mode => 0,
g_irq05_mode => 0,
g_irq06_mode => 0,
g_irq07_mode => 0,
g_irq08_mode => 0,
g_irq09_mode => 0,
g_irq0a_mode => 0,
g_irq0b_mode => 0,
g_irq0c_mode => 0,
g_irq0d_mode => 0,
g_irq0e_mode => 0,
g_irq0f_mode => 0,
g_irq10_mode => 0,
g_irq11_mode => 0,
g_irq12_mode => 0,
g_irq13_mode => 0,
g_irq14_mode => 0,
g_irq15_mode => 0,
g_irq16_mode => 0,
g_irq17_mode => 0,
g_irq18_mode => 0,
g_irq19_mode => 0,
g_irq1a_mode => 0,
g_irq1b_mode => 0,
g_irq1c_mode => 0,
g_irq1d_mode => 0,
g_irq1e_mode => 0,
g_irq1f_mode => 0
)
port map (
clk_i => bus_clock_int,
rst_n_i => rst_n_i,
irq_i => irq_inputs_vector_int,
irq_ack_o => eic_irq_ack_int,
reg_imr_o => eic_imr_int,
reg_ier_i => eic_ier_int,
reg_ier_wr_stb_i => eic_ier_write_int,
reg_idr_i => eic_idr_int,
reg_idr_wr_stb_i => eic_idr_write_int,
reg_isr_o => eic_isr_status_int,
reg_isr_i => eic_isr_clear_int,
reg_isr_wr_stb_i => eic_isr_write_int,
wb_irq_o => wb_irq_o
);
irq_inputs_vector_int(0) <= irq_tag_i;
-- extra code for reg/fifo/mem: FIFO 'Tag Readout Register' data output register 0
process (bus_clock_int, rst_n_i)
begin
if (rst_n_i = '0') then
spll_trr_rdreq_int_d0 <= '0';
elsif rising_edge(bus_clock_int) then
spll_trr_rdreq_int_d0 <= spll_trr_rdreq_int;
end if;
end process;
rwaddr_reg <= wb_addr_i;
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
-- -*- Mode: LUA; tab-width: 2 -*-
peripheral {
name = "WR Softcore PLL";
hdl_entity = "spll_wb_slave";
prefix = "SPLL";
reg {
name = "SPLL Control/Status Register";
prefix = "CSR";
field {
align = 8;
name = "Period detector reference select";
prefix = "PER_SEL";
size = 6;
type = SLV;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
field {
align = 8;
name = "Number of reference channels (max: 32)";
prefix = "N_REF";
type = SLV;
size = 6;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
field {
align = 8;
name = "Number of output channels (max: 8)";
prefix = "N_OUT";
type = SLV;
size = 3;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Output Channel Control Register";
prefix = "OCCR";
field {
align = 8;
name = "Output Channel HW enable flag";
prefix = "OUT_EN";
type = SLV;
size = 8;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
field {
name = "Output Channel locked flag";
prefix = "OUT_LOCK";
type = SLV;
size = 8;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
reg {
name = "Reference Channel Enable Register";
prefix = "RCER";
field {
name = "Reference Channel Enable";
description = "write 1: enables tag generation on the input channel corresponding to the written bit\
write 0: disables tag generation";
type = SLV;
size = 32;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
load = LOAD_EXT;
};
};
reg {
name = "Output Channel Enable Register";
prefix = "OCER";
field {
name = "Output Channel Enable";
description = "write 1: enables tag generation on the output channel corresponding to the written bit\
write 0: disables tag generation";
type = SLV;
size = 8;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
load = LOAD_EXT;
};
};
reg {
name = "HPLL Period Error";
prefix = "PER_HPLL";
field {
name = "Period error value";
prefix = "ERROR";
type = SLV;
size = 16;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
ack_read = "tag_hpll_rd_period_o";
};
field {
name = "Period Error Valid";
prefix = "VALID";
type = BIT;
access_bus = READ_ONLY;
access_dev = WRITE_ONLY;
};
};
reg {
name = "Helper DAC Output";
prefix = "DAC_HPLL";
field {
name = "DAC value";
type = PASS_THROUGH;
size = 16;
};
};
reg {
name = "Main DAC Output";
prefix = "DAC_MAIN";
field {
name = "DAC value";
prefix = "VALUE";
type = PASS_THROUGH;
size = 16;
};
field {
name = "DAC select";
prefix = "DAC_SEL";
description = "Selects the output DAC to be updated with VALUE";
type = PASS_THROUGH;
size = 4;
};
};
reg {
name = "Deglitcher threshold";
prefix = "DEGLITCH_THR";
field {
name = "Threshold";
type = SLV;
size = 16;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
fifo_reg {
name = "Tag Readout Register";
prefix = "TRR";
direction = CORE_TO_BUS;
size = 32;
flags_dev = {FIFO_FULL};
flags_bus = {FIFO_EMPTY};
field {
name = "Tag value";
prefix = "VALUE";
type = SLV;
size = 24;
};
field {
name = "Channel ID";
description = "Tagged Channel ID: 0-31: reference tags, 32-47: output tags";
prefix = "CHAN_ID";
type = SLV;
size = 7;
};
field {
name = "Discontinuous bit";
prefix = "DISC";
description = "1: previous tag has been dropped due to FIFO overflow";
type = BIT;
};
};
irq {
name = "Got a tag";
prefix = "TAG";
trigger = LEVEL_1;
};
};
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for WR Softcore PLL
---------------------------------------------------------------------------------------
-- File : spll_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from wr_softpll.wb
-- Created : Wed Jan 18 13:13:08 2012
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wr_softpll.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wbgen2_pkg.all;
package SPLL_wbgen2_pkg is
-- Input registers (user design -> WB slave)
type t_SPLL_in_registers is record
spll_csr_n_ref_i : std_logic_vector(5 downto 0);
spll_csr_n_out_i : std_logic_vector(2 downto 0);
spll_occr_out_en_i : std_logic_vector(7 downto 0);
spll_rcer_i : std_logic_vector(31 downto 0);
spll_ocer_i : std_logic_vector(7 downto 0);
spll_per_hpll_error_i : std_logic_vector(15 downto 0);
spll_per_hpll_valid_i : std_logic;
spll_trr_wr_req_i : std_logic;
spll_trr_value_i : std_logic_vector(23 downto 0);
spll_trr_chan_id_i : std_logic_vector(6 downto 0);
spll_trr_disc_i : std_logic;
end record;
constant c_SPLL_in_registers_init_value: t_SPLL_in_registers := (
spll_csr_n_ref_i => (others => '0'),
spll_csr_n_out_i => (others => '0'),
spll_occr_out_en_i => (others => '0'),
spll_rcer_i => (others => '0'),
spll_ocer_i => (others => '0'),
spll_per_hpll_error_i => (others => '0'),
spll_per_hpll_valid_i => '0',
spll_trr_wr_req_i => '0',
spll_trr_value_i => (others => '0'),
spll_trr_chan_id_i => (others => '0'),
spll_trr_disc_i => '0'
);
-- Output registers (WB slave -> user design)
type t_SPLL_out_registers is record
spll_csr_per_sel_o : std_logic_vector(5 downto 0);
spll_occr_out_lock_o : std_logic_vector(7 downto 0);
spll_rcer_o : std_logic_vector(31 downto 0);
spll_rcer_load_o : std_logic;
spll_ocer_o : std_logic_vector(7 downto 0);
spll_ocer_load_o : std_logic;
spll_dac_hpll_o : std_logic_vector(15 downto 0);
spll_dac_hpll_wr_o : std_logic;
spll_dac_main_value_o : std_logic_vector(15 downto 0);
spll_dac_main_value_wr_o : std_logic;
spll_dac_main_dac_sel_o : std_logic_vector(3 downto 0);
spll_dac_main_dac_sel_wr_o : std_logic;
spll_deglitch_thr_o : std_logic_vector(15 downto 0);
spll_trr_wr_full_o : std_logic;
end record;
constant c_SPLL_out_registers_init_value: t_SPLL_out_registers := (
spll_csr_per_sel_o => (others => '0'),
spll_occr_out_lock_o => (others => '0'),
spll_rcer_o => (others => '0'),
spll_rcer_load_o => '0',
spll_ocer_o => (others => '0'),
spll_ocer_load_o => '0',
spll_dac_hpll_o => (others => '0'),
spll_dac_hpll_wr_o => '0',
spll_dac_main_value_o => (others => '0'),
spll_dac_main_value_wr_o => '0',
spll_dac_main_dac_sel_o => (others => '0'),
spll_dac_main_dac_sel_wr_o => '0',
spll_deglitch_thr_o => (others => '0'),
spll_trr_wr_full_o => '0'
);
function "or" (left, right: t_SPLL_in_registers) return t_SPLL_in_registers;
function f_x_to_zero (x:std_logic) return std_logic;
end package;
package body SPLL_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is
begin
if(x = 'X' or x = 'U') then
return '0';
else
return x;
end if;
end function;
function "or" (left, right: t_SPLL_in_registers) return t_SPLL_in_registers is
variable tmp: t_SPLL_in_registers;
begin
tmp.spll_csr_n_ref_i := left.spll_csr_n_ref_i or right.spll_csr_n_ref_i;
tmp.spll_csr_n_out_i := left.spll_csr_n_out_i or right.spll_csr_n_out_i;
tmp.spll_occr_out_en_i := left.spll_occr_out_en_i or right.spll_occr_out_en_i;
tmp.spll_rcer_i := left.spll_rcer_i or right.spll_rcer_i;
tmp.spll_ocer_i := left.spll_ocer_i or right.spll_ocer_i;
tmp.spll_per_hpll_error_i := left.spll_per_hpll_error_i or right.spll_per_hpll_error_i;
tmp.spll_per_hpll_valid_i := left.spll_per_hpll_valid_i or right.spll_per_hpll_valid_i;
tmp.spll_trr_wr_req_i := left.spll_trr_wr_req_i or right.spll_trr_wr_req_i;
tmp.spll_trr_value_i := left.spll_trr_value_i or right.spll_trr_value_i;
tmp.spll_trr_chan_id_i := left.spll_trr_chan_id_i or right.spll_trr_chan_id_i;
tmp.spll_trr_disc_i := left.spll_trr_disc_i or right.spll_trr_disc_i;
return tmp;
end function;
end package body;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment