Xilinx XC9572 CPLD based Clock Divider generates a desirable clock by adjusting the DIP switches on the board.The output clock signal, since generated from a CPLD,i.e. completely digital circuit is almost jitter-free. This is suitable for the next circuit i.e. the PRBS Generator itself. To change the frequency of the randomness of the generated signal we just have to change the clock being generated by this circuit.
Xilinx XC2C64A CPLD based 8-bit PRBS Generator is the actual PRBS generator circuit. This particular CPLD is configured to generate an 8-bit random signal. It can be configured to generate a wider signal, like say 16-bit PRBS signal by just changing the VHDL code. However, if an analog signal is needed then we will have to feed this signal to a DAC.
8-bit R-2R DAC to convert digital PRBS signal to analog voltage as viewed in the oscilloscope.
https://www.youtube.com/watch?v=M5WpqgEG1Cc
VHDL Code for D-Flipflop
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity dff is
Port ( CLK : in std_logic;
RSTn : in std_logic;
D : in std_logic;
Q : out std_logic);
end dff;
architecture Behavioral of dff is
begin
process(CLK)
begin
if CLK'event and CLK='1' then
if RSTn='1' then
Q <= '1';
else
Q <= D;
end if;
end if;
end process;
end Behavioral;
VHDL Code for PRBS Generator using LFSR
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity lfsr is
Port ( CLK : in STD_LOGIC;
RSTn : in STD_LOGIC;
data_out : out STD_LOGIC_VECTOR (7 downto 0));
end lfsr;
architecture Behavioral of lfsr is
component dff
Port ( CLK : in std_logic;
RSTn : in std_logic;
D : in std_logic;
Q : out std_logic);
end component;
signal data_reg : std_logic_vector(7 downto 0);
signal tap_data : std_logic;
begin
process(CLK)
begin
tap_data <= (data_reg(1) xor data_reg(2)) xor (data_reg(4) xor
data_reg(7));
end process;
stage0: dff
port map(CLK, RSTn, tap_data, data_reg(0));
g0:for i in 0 to 6 generate
stageN: dff
port map(CLK, RSTn, data_reg(i), data_reg(i+1));
end generate;
data_out <= data_reg after 3 ns;
end Behavioral;
VHDL Test-Bench Code for Simulating PRBS Generator using LFSR
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY testprbs IS
END testprbs;
ARCHITECTURE behavior OF testprbs IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT lfsr
PORT(
CLK : IN std_logic;
RSTn : IN std_logic;
data_out : OUT std_logic_vector(7 downto 0)
);
END COMPONENT;
signal CLK : std_logic := '0';
signal RSTn : std_logic := '0';
signal data_out : std_logic_vector(7 downto 0);
-- Clock period definitions
constant CLK_period : time := 10 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: lfsr PORT MAP (
CLK => CLK,
RSTn => RSTn,
data_out => data_out
);
CLK_process :process
begin
CLK <= '0';
wait for CLK_period/2;
CLK <= '1';
wait for CLK_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
wait for 10 ns;
wait for CLK_period*1;
RSTn <= '1';
wait for CLK_period*1;
RSTn <= '0';
wait;
end process;
END;
VHDL Code for Clock Divider
--Programmable Clock Diveder Circuit
--Engineer: Debashish Mohapatra, 9938040894
--Input Clock Frequency 4MHz, 11.059 Mhz, 16 MHz, 24 MHz
--An 8 bit selector push button array to set the divide by factor
--Square of the factor_select input to set the prescaler
--e.g. is select switch inpput reads 3, then-- prescaler is set to square of 3 i.e. 9
-------------------------------------------
library IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
entity clock_divider is
Port ( clk_in : in STD_LOGIC;
rst : in STD_LOGIC;
factor_select : in STD_LOGIC_VECTOR (7 downto 0);
sw : in std_logic;
LED : out std_logic;
clk_out : out STD_LOGIC);
end clock_divider;
architecture Behavioral of clock_divider is
signal factor_final : std_logic_vector (15 downto 0);
-- signal factor_usgn : unsigned (7 downto 0);
-- signal factor_int : integer :=0;
signal prescaler : integer :=0;
signal counter : integer := 0;
signal temp_clk_out : std_logic;
-- signal count_out : integer :=0;
signal led_state : std_logic := '0';
begin
factor_final <= factor_select & factor_select;
-- factor_usgn <= unsigned (factor_select);
-- --Std logic vector to unsigned conversion
-- factor_int <= to_integer(factor_usgn);
-- --Unsigned to Integer conversion
-- -- Or factor_int <= to_integer(unsigned(factor_select));
-- prescaler <= factor_int;
-- -- set prescler to the integer equivalent of the read value from buttons
frequency_divider:process(rst, clk_in, sw) begin
if (rst = '0') then
temp_clk_out <= '0';
counter <= 0;
elsif rising_edge(clk_in) then
if (sw = '0') then
prescaler <= to_integer(unsigned(factor_select));
elsif (sw ='1') then
prescaler <= to_integer(unsigned(factor_final));
else
prescaler <= 0;
end if;
if (counter = prescaler) then
temp_clk_out <= not(temp_clk_out);
counter <= 0;
led_state <= not (led_state);
else
counter <= counter + 1;
end if;
end if;
end process;
clk_out <= temp_clk_out;
-- led_blinking : process (temp_clk_out) begin
-- if rising_edge(temp_clk_out) then
-- if (count_out = 256) then
-- count_out <= 0;
-- led_state <= not (led_state);
-- else
-- count_out <= count_out +1;
-- end if;
-- end if;
-- end process;
led <= led_state;
end Behavioral;