Custom Clocking

From FPGA Wiki

Jump to: navigation, search

The build in clock on the Spartan 3E, tied to pin C9, runs at 50MHz. Depending on the delay of your circuits and latches, it may be helpful to change this. Luckily, Xilinx has a wizard built-in to do just this.

Creating the Component

Xilinx does not actually change the clock speed of the FPGA. Instead, it creates a component (just like any other) that takes as input the default clock of 50 MHz and outputs a new clock signal at a new frequency. To do this, right click on the top-level component in the left frame of Xilinx and select "New Source...". When the dialog comes up, choose "IP (CORE Generator & Architecture Wizard". Give the file a name and press next:

Image:Cc1.jpg

In the next window, navigate to FPGA Features and Design -> Clocking -> Spartan-3E, Spartan-3A and choose "Single DCM v9.1i" as shown below:

Image:Cc2.jpg

Press "Next" then "Finish". The wizard below will appear. Enter the settings shown:

Image:Cc3.jpg

Press "Next" twice to skip the "Clock Buffers" portion of the wizard. The following screen will appear. Enter the desired clock frequency as shown below with 5 MHz and press "Next" then "Finish".

Image:Cc4.jpg

Adding the Clock to the Datapath

There should now be a new element, named what you entered previously, in the left pane of Xilinx. Select it and there should be new options in the "Processes" pane. One is "View HDL Instantiation Template" as shown below. Double click it:

Image:Cc5.jpg

This has two parts two it: the first is a component prototype:

COMPONENT timer
PORT(
	CLKIN_IN : IN std_logic;
	RST_IN : IN std_logic;          
	CLKFX_OUT : OUT std_logic;
	CLK0_OUT : OUT std_logic;
	LOCKED_OUT : OUT std_logic
	);
END COMPONENT;

The second is the structural constructor (the label Inst_timer will be different depending on what you named the clock):

Inst_timer: timer PORT MAP(
	CLKIN_IN => ,
	RST_IN => ,
	CLKFX_OUT => ,
	CLK0_OUT => ,
	LOCKED_OUT => 
);

Now, go to your top level component of the MIPS datapath. There should be some clock input signal that is currently mapped to the pin C9 (50 MHz clock). This input then sends the clock signal to the contained components (registers, PC, etc.). We need to change this to instead send that 50MHz signal into the timer component's CLKIN_IN which will adjust the frequency and output it through CLK0_OUT.

For example, if your top level component is currently:

entity mips_datapath is
	port (
		clk_in : in std_logic;
		output : out std_logic_vector(31 downto 0)
	);
end mips_datapath;

architecture structural of single_cycle is

-- ... Components, signals, etc ...

begin
	first_component: some_component port map(clk => clk_in, ...);
	second_component: some_other_component port map(clk => clk_in, ...);
end structural;

This would be changed to:

entity mips_datapath is
	port (
		clk_in : in std_logic;
		output : out std_logic_vector(31 downto 0)
	);
end mips_datapath;

architecture structural of single_cycle is

-- ... Components, signals, etc ...
component timer
	port(
		CLKIN_IN : IN std_logic;
		RST_IN : IN std_logic;          
		CLKFX_OUT : OUT std_logic;
		CLK0_OUT : OUT std_logic;
		LOCKED_OUT : OUT std_logic
	);
end component;

signal modified_clock : std_logic := '0';

begin
	Inst_timer: timer port map(
		RST_IN => '0',
		CLKIN_IN => clk_in,
		CLK0_OUT => modified_clock
	);

	first_component: some_component port map(clk => modified_clock, ...);
	second_component: some_other_component port map(clk => modified_clock, ...);
end structural;

As you can see, the clock coming into the mips_datapath component is no longer directly sent to components but first through the new timer component that changes its frequency. Only after that is the next clock, modified_clock sent into other components.

Personal tools
extra