diff options
Diffstat (limited to 'source/controller.v')
| -rw-r--r-- | source/controller.v | 472 |
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 |



