summaryrefslogtreecommitdiffhomepage
path: root/source/controller.v
diff options
context:
space:
mode:
Diffstat (limited to 'source/controller.v')
-rw-r--r--source/controller.v472
1 files changed, 0 insertions, 472 deletions
diff --git a/source/controller.v b/source/controller.v
deleted file mode 100644
index 2b95d1e..0000000
--- a/source/controller.v
+++ /dev/null
@@ -1,472 +0,0 @@
-/*
- * controller.v
- *
- * Copyright (C) 2018, 2109, 2020, 2021 Mind Chasers Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- * function: FPGA internal state machine controller
- *
- */
-
-`timescale 1ns /10ps
-
-module controller #(parameter ADDR_SZ = 7)
-(
- input rstn,
- input clk,
- input init,
- input pulse_100ms,
-
- // PCS status lines
- input [3:0] pcs_rx_error,
- input [1:0] pll_lol,
-
- // link status
- input [3:0] port_up,
-
- // mdio_controller interface
- output reg mdio_cont_start,
- input mdio_cont_done,
- output reg [ADDR_SZ-1:0] mdio_routine_addr,
- input mdio_run, // the mdio controller is active
-
- // mdio_data params
- output reg [4:0] mdio_page,
- output reg [4:0] mdio_reg_addr,
- output reg [7:0] mdio_w_data_h,
- output reg [7:0] mdio_w_data_l,
-
- // bin_to_ascii interface for MDIO or CONT -> bin_to_ascii -> FIFO -> I2C
- input bin_to_ascii_run, // asserted if block is active and writing FIFO
-
- // sync_fifo interface: controller to fifo
- output fifo_mux_sel, // 0 is self, 1 is mdio_controller
- output reg fifo_we,
- output reg [6:0] read_fifo_d_o,
-
- // i2c interface: i2c to controller
- input i2c_rx_we,
- input i2c_rx_done,
- input [7:0] i2c_d_in,
-
- // DCU Resets
- output [1:0] pcs_rst_dual,
- output [1:0] serdes_rst_dual,
- output [1:0] tx_serdes_rst,
-
- // Channel
- output [3:0] phy_resetn,
- output [3:0] mac_reset,
-
- output [3:0] tx_pcs_rst,
- output [3:0] rx_serdes_rst,
- output [3:0] rx_pcs_rst,
-
- output reg [1:0] mdio_mux_sel,
-
- // TX custom packet
- output reg tx_custom
-
-);
-
- // state encoding
- localparam BUFFER_SZ = 8; // index starts at 1, 0 is cmd
-
- localparam S0= 4'h0, S1=4'h1, S2=4'h2, S3=4'h3,
- S4= 4'h4, S5=4'h5, S6=4'h6, S7=4'h7,
- S8= 4'h8, S9=4'h9, S10=4'ha, S11=4'hb,
- S12= 4'hc, S13=4'hd, S14=4'he, S15=4'hf;
-
- // ascii codes we use
- localparam ASCIIc = 7'h63, // channel resets
- ASCIId = 7'h64, // set and dump page
- ASCIIf = 7'h66, // FIFO control
- ASCIIi = 7'h69, // init ( sgmii mode )
- ASCIIl = 7'h6c, // link status
- ASCIIm = 7'h6d, // mdio mux
- ASCIIp = 7'h70, // PCS /SERDES block status
- ASCIIq = 7'h71,
- ASCIIr = 7'h72, // set address and read reg
- ASCIIs = 7'h73, // show mdio line status
- ASCIIt = 7'h74, // transmit test packet
- ASCIIu = 7'h75,
- ASCIIw = 7'h77, // write reg at preset page and address
- ASCIIx = 7'h78, // control word
- ASCIIy = 7'h79, // extended read
- ASCIIz = 7'h7a, // extended write
- ASCII_ = 7'h5f,
- LF = 7'h0a,
- CR = 7'h0d;
-
- reg [1:0] x_reg[0:3]; // ASCIIx: phy_reset and mac_reset
- reg [2:0] c_reg[0:3]; // ASCIIc one reg per channel
- reg [2:0] u_reg[0:1]; // 2 DCU's: pcs_rst_dual, serdes_rst_dual, tx_serdes_rst
-
- reg [3:0] cont_state;
- reg [3:0] cnt; // input cnt, 0 is cmd, 1-8 are buffer, beyond are thrown out & flag is set
- reg [6:0] cmd;
- integer i;
-
- reg [6:0] buffer [1:BUFFER_SZ]; // data buffer
-
- reg mdio_cmd, cont_cmd;
- wire rx_cmd;
- reg mdio_cont_busy;
-
- wire[5:0] pcs_s;
- wire[3:0] link_s;
-
- reg cont_start, cont_busy, cont_done;
-
- assign pcs_s = { pll_lol, pcs_rx_error };
- assign link_s = port_up;
-
- /*
- * main state machine for controller
- */
- always @(posedge clk or negedge rstn)
- begin
- if ( !rstn )
- cont_state <= S0;
- else
- case (cont_state)
- S0: cont_state <= S1; // S0 is default on reset
- S1: if ( rx_cmd && cont_cmd )
- cont_state <= S2;
- else if ( rx_cmd )
- cont_state <= S3;
- S2: cont_state <= S3; // respond to cont cmd
- S3: if ( !cont_busy )
- cont_state <= S4;
- S4: if ( !mdio_cont_busy )
- cont_state <= S1;
- default: cont_state <= cont_state;
- endcase
- end
-
-/*
-* Controller Tasks, controller always runs upon rx_cmd.
-* Other tasks will hold off until cont_done asserts
-*/
- always @(posedge clk or negedge rstn)
- begin
- if ( !rstn )
- cont_start <= 1'b0;
- else if ( rx_cmd )
- cont_start <= 1'b1;
- else
- cont_start <= 1'b0;
- end
-
- // cont_busy
- always @(posedge clk or negedge rstn)
- begin
- if ( !rstn )
- cont_busy <= 1'b0;
- else if ( cont_start )
- cont_busy <= 1'b1;
- else if ( cont_done )
- cont_busy <= 1'b0;
- end
-
- // cont_done
- always @(posedge clk or negedge rstn)
- begin
- if ( !rstn )
- cont_done <= 1'b0;
- else if ( cont_busy )
- cont_done <= 1'b1;
- else
- cont_done <= 1'b0;
- end
-
- always @(cmd)
- begin
- if ( cmd == ASCIIp || cmd == ASCIIl )
- cont_cmd <= 1'b1;
- else
- cont_cmd <= 1'b0;
- end
-
- /*
- * MDIO controller related
- */
- always @(cmd)
- begin
- if ( cmd == ASCIIi || cmd == ASCIIs || cmd == ASCIId || cmd == ASCIIr || cmd == ASCIIw || cmd == ASCIIy || cmd == ASCIIz )
- mdio_cmd <= 1'b1;
- else
- mdio_cmd <= 1'b0;
- end
-
-
- always @(posedge clk or negedge rstn)
- begin
- if ( !rstn )
- mdio_cont_start <= 1'b0;
- else if ( cont_done && mdio_cmd )
- mdio_cont_start <= 1'b1;
- else
- mdio_cont_start <= 1'b0;
- end
-
- /*
- * driver: mdio_route_addr
- */
- always @(posedge clk or negedge rstn)
- begin
- if ( !rstn )
- mdio_routine_addr <= 'd0;
- else if ( cont_done && mdio_cmd )
- if ( cmd == ASCIIi )
- mdio_routine_addr <= 'd0;
- else if ( cmd == ASCIIs )
- mdio_routine_addr <= 'd20;
- else if ( cmd == ASCIId )
- mdio_routine_addr <= 'd25;
- else if ( cmd == ASCIIr )
- mdio_routine_addr <= 'd48;
- else if ( cmd == ASCIIw )
- mdio_routine_addr <= 'd50;
- else if ( cmd == ASCIIy )
- mdio_routine_addr <= 'd60;
- else if ( cmd == ASCIIz )
- mdio_routine_addr <= 'd80;
- end
-
- // mdio_cont_busy
- always @(posedge clk or negedge rstn)
- begin
- if ( !rstn )
- mdio_cont_busy <= 1'b0;
- else if ( mdio_cont_start )
- mdio_cont_busy <= 1'b1;
- else if ( mdio_cont_done )
- mdio_cont_busy <= 1'b0;
- end
-
- /* fifo_mux_sel = 1 when controller does NOT have FIFO bus */
- assign fifo_mux_sel = mdio_cont_busy | mdio_run;
-
- /* set mdio page */
- always @(posedge clk or negedge rstn)
- begin
- if ( !rstn )
- mdio_page <= 'd0;
- else if ( rx_cmd && cmd == ASCIId )
- mdio_page <= { buffer[1][0], buffer[2][3:0] };
- end
-
- /* set mdio_reg_addr */
- always @(posedge clk or negedge rstn)
- begin
- if ( !rstn )
- mdio_reg_addr <= 'd0;
- else if ( rx_cmd && cmd == ASCIIr )
- mdio_reg_addr <= { buffer[1][0], buffer[2][3:0] };
- end
-
- /* set mdio_w_data_l and mdio_w_data_h */
- always @(posedge clk or negedge rstn)
- begin
- if ( !rstn )
- begin
- mdio_w_data_l <= 'd0;
- mdio_w_data_h <= 'd0;
- end
- else if ( rx_cmd && (cmd == ASCIIw || cmd == ASCIIy || cmd == ASCIIz ) )
- begin
- mdio_w_data_h <= { buffer[1][3:0], buffer[2][3:0] };
- mdio_w_data_l <= { buffer[3][3:0], buffer[4][3:0] };
- end
- end
-
- // Channel Resets
- always @(posedge clk or negedge rstn)
- begin
- if ( !rstn )
- begin
- c_reg[0] <= 'hff;
- c_reg[1] <= 'hff;
- c_reg[2] <= 'hff;
- c_reg[3] <= 'hff;
- end
- else if ( rx_cmd && cmd == ASCIIc )
- begin
- c_reg[0] <= buffer[4][2:0];
- c_reg[1] <= buffer[3][2:0];
- c_reg[2] <= buffer[2][2:0];
- c_reg[3] <= buffer[1][2:0];
- end
- end
-
- assign rx_pcs_rst[0] = c_reg[0][0];
- assign rx_serdes_rst[0] = c_reg[0][1];
- assign tx_pcs_rst[0]= c_reg[0][2];
-
- assign rx_pcs_rst[1] = c_reg[1][0];
- assign rx_serdes_rst[1] = c_reg[1][1];
- assign tx_pcs_rst[1]= c_reg[1][2];
-
- assign rx_pcs_rst[2] = c_reg[2][0];
- assign rx_serdes_rst[2] = c_reg[2][1];
- assign tx_pcs_rst[2]= c_reg[2][2];
-
- assign rx_pcs_rst[3] = c_reg[3][0];
- assign rx_serdes_rst[3] = c_reg[3][1];
- assign tx_pcs_rst[3]= c_reg[3][2];
-
- /* DCU resets */
- always @(posedge clk or negedge rstn)
- begin
- if ( !rstn )
- begin
- u_reg[0] <= 'hff;
- u_reg[1] <= 'hff;
- end
- else if ( rx_cmd && cmd == ASCIIu )
- begin
- u_reg[0] <= buffer[2][2:0];
- u_reg[1] <= buffer[1][2:0];
- end
- end
-
- // DCU0 Reset assignments
- assign pcs_rst_dual[0] = u_reg[0][2];
- assign serdes_rst_dual[0] = u_reg[0][1];
- assign tx_serdes_rst[0] = u_reg[0][0];
-
- // DCU1 Reset assignments
- assign pcs_rst_dual[1] = u_reg[1][2];
- assign serdes_rst_dual[1] = u_reg[1][1];
- assign tx_serdes_rst[1] = u_reg[1][0];
-
- /* X control */
- always @(posedge clk or negedge rstn)
- begin
- if ( !rstn )
- begin
- x_reg[0] <= 'hff;
- x_reg[1] <= 'hff;
- x_reg[2] <= 'hff;
- x_reg[3] <= 'hff;
-
- end
- else if ( rx_cmd && cmd == ASCIIx )
- begin
- x_reg[0] <= buffer[4][1:0];
- x_reg[1] <= buffer[3][1:0];
- x_reg[2] <= buffer[2][1:0];
- x_reg[3] <= buffer[1][1:0];
-
- end
- end
-
- assign mac_reset[0] = x_reg[0][0];
- assign phy_resetn[0] = ~x_reg[0][1];
-
- assign mac_reset[1] = x_reg[1][0];
- assign phy_resetn[1] = ~x_reg[1][1];
-
- assign mac_reset[2] = x_reg[2][0];
- assign phy_resetn[2] = ~x_reg[2][1];
-
- assign mac_reset[3] = x_reg[3][0];
- assign phy_resetn[3] = ~x_reg[3][1];
-
-
- /* mdio_mux_sel */
- always @(posedge clk or negedge rstn)
- begin
- if ( !rstn )
- mdio_mux_sel <= 'h0;
- else if ( rx_cmd && cmd == ASCIIm )
- mdio_mux_sel <= buffer[1][1:0];
- end
-
- /* transmit custom packet */
- always @(posedge clk or negedge rstn)
- begin
- if ( !rstn )
- tx_custom <= 1'b0;
- else if ( rx_cmd && cmd == ASCIIt )
- tx_custom <= 1'b1;
- else
- tx_custom <= 1'b0;
- end
-
- /* FIFO logic */
- always @(posedge clk or negedge rstn)
- begin
- if ( !rstn )
- fifo_we <= 1'b0;
- else if ( cont_state == S2 )
- fifo_we <= 1'b1;
- else
- fifo_we <= 1'b0;
- end
-
-
- always @(posedge clk or negedge rstn)
- begin
- if ( !rstn )
- read_fifo_d_o <= 0;
- else if ( cont_state == S2 && cmd == ASCIIp ) // pcs status
- read_fifo_d_o <= { 1'b0, pcs_s };
- else if ( cont_state == S2 && cmd == ASCIIl ) // link status
- read_fifo_d_o <= { 3'b000, link_s };
- end
-
- /*
- * capture the cmd and buffer
- * rx_cmd is a one shot at the end that triggers the state machine
- */
- assign rx_cmd = i2c_rx_done;
-
- always @(posedge clk or negedge rstn)
- begin
- if ( !rstn )
- cmd <= 7'h0;
- else if ( i2c_rx_we && cnt == 4'h0 )
- cmd <= i2c_d_in;
- end
-
- always @(posedge clk or negedge rstn)
- begin
- if ( !rstn )
- begin
- for (i=1; i<=BUFFER_SZ; i=i+1)
- begin
- buffer[i] <= 'h0;
- end
- end
- else if ( i2c_rx_we && cnt > 0 && cnt <= BUFFER_SZ )
- buffer[cnt] <= i2c_d_in;
- end
-
- /*
- * counter for I2c rx buffer.
- */
- always @(posedge clk or negedge rstn)
- begin
- if ( !rstn )
- cnt <= 'h0;
- else if (i2c_rx_done)
- cnt <= 'h0;
- else if (i2c_rx_we )
- cnt <= cnt + 1;
- end
-
-
-endmodule

Highly Recommended Verilog Books