HITDAQ/FPGA_firmware/q_sys/synthesis/submodules/sequencer_pll_mgr.sv
2024-10-11 14:49:54 +02:00

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