194 lines
5.6 KiB
Systemverilog
194 lines
5.6 KiB
Systemverilog
// (C) 2001-2019 Intel Corporation. All rights reserved.
|
|
// Your use of Intel Corporation's design tools, logic functions and other
|
|
// software and tools, and its AMPP partner logic functions, and any output
|
|
// files from any of the foregoing (including device programming or simulation
|
|
// files), and any associated documentation or information are expressly subject
|
|
// to the terms and conditions of the Intel Program License Subscription
|
|
// Agreement, Intel FPGA IP License Agreement, or other applicable
|
|
// license agreement, including, without limitation, that your use is for the
|
|
// sole purpose of programming logic devices manufactured by Intel and sold by
|
|
// Intel or its authorized distributors. Please refer to the applicable
|
|
// agreement for further details.
|
|
|
|
|
|
// ******
|
|
// pll_mgr
|
|
// ******
|
|
//
|
|
// PLL Manager
|
|
//
|
|
// General Description
|
|
// -------------------
|
|
//
|
|
// This component allows a way for a master on the Avalon bus to
|
|
// control PLL output clock phase during calibration
|
|
|
|
//
|
|
|
|
`timescale 1 ps / 1 ps
|
|
|
|
module sequencer_pll_mgr (
|
|
// Avalon Interface
|
|
|
|
avl_clk,
|
|
avl_reset_n,
|
|
avl_address,
|
|
avl_write,
|
|
avl_writedata,
|
|
avl_read,
|
|
avl_readdata,
|
|
avl_waitrequest,
|
|
|
|
// PLL control
|
|
|
|
phasecounterselect,
|
|
phasestep,
|
|
phaseupdown,
|
|
scanclk,
|
|
phasedone,
|
|
|
|
afi_init_req,
|
|
afi_cal_req
|
|
);
|
|
|
|
parameter AVL_DATA_WIDTH = 32;
|
|
parameter AVL_ADDR_WIDTH = 1;
|
|
|
|
localparam PHASE_COUNTER_WIDTH = 16;
|
|
localparam PLL_COUNTER_BIT_WIDTH = 3;
|
|
localparam PLL_COUNTER = 2;
|
|
|
|
input avl_clk;
|
|
input avl_reset_n;
|
|
input [AVL_ADDR_WIDTH - 1:0] avl_address;
|
|
input avl_write;
|
|
input [AVL_DATA_WIDTH - 1:0] avl_writedata;
|
|
input avl_read;
|
|
output [AVL_DATA_WIDTH - 1:0] avl_readdata;
|
|
output avl_waitrequest;
|
|
|
|
output [PLL_COUNTER_BIT_WIDTH - 1:0] phasecounterselect;
|
|
output phasestep;
|
|
output phaseupdown;
|
|
output scanclk;
|
|
input phasedone;
|
|
|
|
input afi_init_req;
|
|
input afi_cal_req;
|
|
|
|
logic scanclk;
|
|
logic [PHASE_COUNTER_WIDTH - 1:0] mem_array [PLL_COUNTER - 1:0];
|
|
logic [AVL_DATA_WIDTH - 1:0] avl_readdata;
|
|
logic int_waitrequest;
|
|
|
|
logic [AVL_ADDR_WIDTH - 1:0] int_address;
|
|
logic [AVL_DATA_WIDTH - 1:0] int_writedata;
|
|
|
|
logic [PLL_COUNTER_BIT_WIDTH - 1:0] phasecounterselect;
|
|
logic phasestep;
|
|
logic phaseupdown;
|
|
|
|
typedef enum int unsigned {
|
|
IDLE,
|
|
WRITE,
|
|
PLLWAIT,
|
|
PLLWAIT2,
|
|
PLLWAIT3,
|
|
READ,
|
|
READWAIT
|
|
} PLL_MGR_STATE;
|
|
|
|
PLL_MGR_STATE state;
|
|
|
|
assign scanclk = avl_clk;
|
|
assign avl_waitrequest = ((state == IDLE) && ((avl_read == 1) || (avl_write == 1))) ? 1'b1 : int_waitrequest;
|
|
|
|
// State machine
|
|
|
|
always_ff @ (posedge avl_clk or negedge avl_reset_n)
|
|
begin
|
|
if (avl_reset_n == 0)
|
|
begin
|
|
state <= IDLE;
|
|
avl_readdata <= 0;
|
|
int_waitrequest <= 0;
|
|
for (int i=0; i < PLL_COUNTER; i++)
|
|
mem_array[i] <= 0;
|
|
phasecounterselect <= 0;
|
|
phasestep <= 0;
|
|
phaseupdown <= 0;
|
|
end
|
|
else
|
|
begin
|
|
case(state)
|
|
IDLE :
|
|
begin
|
|
int_waitrequest <= 0;
|
|
if (avl_write)
|
|
begin
|
|
state <= WRITE;
|
|
int_waitrequest <= 1;
|
|
end
|
|
else if (avl_read)
|
|
begin
|
|
state <= READ;
|
|
int_waitrequest <= 1;
|
|
end
|
|
end
|
|
WRITE :
|
|
begin
|
|
if (int_writedata[0])
|
|
mem_array [int_address] <= mem_array [int_address] + 1'b1;
|
|
else
|
|
mem_array [int_address] <= mem_array [int_address] - 1'b1;
|
|
|
|
phaseupdown <= int_writedata[0];
|
|
phasecounterselect <= int_address[2:0] + 3'd4;
|
|
phasestep <= 1;
|
|
state <= PLLWAIT;
|
|
end
|
|
PLLWAIT :
|
|
state <= PLLWAIT2;
|
|
PLLWAIT2 :
|
|
begin
|
|
state <= PLLWAIT3;
|
|
int_waitrequest <= 0;
|
|
end
|
|
PLLWAIT3 :
|
|
begin
|
|
phasestep <= 0;
|
|
state <= IDLE;
|
|
end
|
|
READ :
|
|
begin
|
|
if (int_address < PLL_COUNTER)
|
|
avl_readdata <= mem_array [int_address];
|
|
else
|
|
avl_readdata <= afi_init_req | afi_cal_req;
|
|
int_waitrequest <= 0;
|
|
state <= READWAIT;
|
|
end
|
|
READWAIT :
|
|
begin
|
|
state <= IDLE;
|
|
end
|
|
endcase
|
|
end
|
|
end
|
|
|
|
always_ff @ (posedge avl_clk or negedge avl_reset_n)
|
|
begin
|
|
if (avl_reset_n == 0)
|
|
begin
|
|
int_address <= 0;
|
|
int_writedata <= 0;
|
|
end
|
|
else
|
|
begin
|
|
int_address <= avl_address;
|
|
int_writedata <= avl_writedata;
|
|
end
|
|
end
|
|
|
|
endmodule
|