From c8b273c80abe98e53828f46079a187975938a56a Mon Sep 17 00:00:00 2001 From: Private Island Networks Date: Mon, 1 Sep 2025 12:34:17 -0400 Subject: rename source to src --- source/an.v | 122 ------ source/bin_to_ascii.v | 128 ------- source/cam.v | 85 ----- source/clk_gen.v | 67 ---- source/controller.v | 472 ----------------------- source/directives.v | 34 -- source/dpram.v | 102 ----- source/drop_fifo.v | 176 --------- source/ethernet_params.v | 39 -- source/fcs.v | 142 ------- source/half_fifo.v | 194 ---------- source/i2c.v | 391 ------------------- source/interrupts.v | 77 ---- source/ipv4.v | 152 -------- source/link_timer.v | 67 ---- source/mac.v | 973 ----------------------------------------------- source/mdio.v | 146 ------- source/mdio_cont.v | 159 -------- source/mdio_data_ti.v | 128 ------- source/metrics.v | 102 ----- source/pkt_filter.v | 95 ----- source/sgmii_params.v | 55 --- source/spi.v | 315 --------------- source/switch.v | 531 -------------------------- source/sync_fifo.v | 110 ------ 25 files changed, 4862 deletions(-) delete mode 100644 source/an.v delete mode 100644 source/bin_to_ascii.v delete mode 100644 source/cam.v delete mode 100644 source/clk_gen.v delete mode 100644 source/controller.v delete mode 100644 source/directives.v delete mode 100644 source/dpram.v delete mode 100644 source/drop_fifo.v delete mode 100644 source/ethernet_params.v delete mode 100644 source/fcs.v delete mode 100644 source/half_fifo.v delete mode 100644 source/i2c.v delete mode 100644 source/interrupts.v delete mode 100644 source/ipv4.v delete mode 100644 source/link_timer.v delete mode 100644 source/mac.v delete mode 100644 source/mdio.v delete mode 100644 source/mdio_cont.v delete mode 100644 source/mdio_data_ti.v delete mode 100644 source/metrics.v delete mode 100644 source/pkt_filter.v delete mode 100644 source/sgmii_params.v delete mode 100644 source/spi.v delete mode 100644 source/switch.v delete mode 100644 source/sync_fifo.v (limited to 'source') diff --git a/source/an.v b/source/an.v deleted file mode 100644 index 18b5d95..0000000 --- a/source/an.v +++ /dev/null @@ -1,122 +0,0 @@ -/* - * an.v - * - * Copyright 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: Auto Negotiation - * - * Notes: a simplified version of AN suitable for SGMII only (not 1000BASE-SX) - */ - -`timescale 1ns /10ps - -module an( - input rstn, - input phy_resetn, // The external PHY has its reset signal asserted - input clk, - - // AN - input [1:0] phy_type, // SGMII==0, SX=1, SMA=3 - input pulse_1_6ms, // SGMII - input pulse_10ms, // SX - input [1:0] fixed_speed, - input an_disable, - output reg an_duplex, - output reg [1:0] an_speed, - output reg an_link_up, - output reg [15:0] tx_config_reg, - output reg phy_up, - - input rx_k_m1, - input rx_k_m2, - input rx_k_m3, - input rx_k_m4, - - input [7:0] rx_data_m1, - input [7:0] rx_data_m2, - input [7:0] rx_data_m3, - input [7:0] rx_data_m4 - - // Debug -); - -`include "sgmii_params.v" -`include "ethernet_params.v" - -localparam PHY_TYPE_SGMII = 2'b00, - PHY_TYPE_SX = 2'b01, - PHY_TYPE_RSVD = 2'b10, - PHY_TYPE_SMA = 2'b11; - - -localparam AN_TYPE_SX = 1'b0, - AN_TYPE_SGMII = 1'b1; - -localparam AN_ST_DISABLE=4'h0, AN_ST_ENABLE=4'h1, AN_ST_RESTART=4'h2, - AN_ST_ABILITY_DETECT=4'h3, AN_ST_ACK_DETECT=4'h4, - AN_ST_COMPLETE_ACK=4'h5, AN_ST_IDLE_DETECT=4'h6, AN_ST_LINK_OK=4'h7; - -// AN -reg [2:0] an_state; -wire an_ability_detect; -wire an_link_timer_pulse; -reg rx_config_detect; -reg [15:0] rx_config_reg, tx_config_reg; -reg [1:0] rx_config_cnt; // use to count consecutive rx config_regs - -/* - * SGMII Auto Negotiation State Machine - * Look for configuration /C/ ordered set - * /C/ is Alternating /C1/ and /C2/ - * /C1/: /K28.5/D21.5(0xb5)/Config_Reg - * /C2/: /K28.5/D2.2(0x42)/Config_Reg - * Config Reg: Low High - */ -always @(posedge clk or negedge rstn) - if (!rstn) - begin - an_link_up <= 1'b0; - an_duplex <= 1'b0; - an_speed <= SGMII_SPEED_RSVD; - phy_up <= 1'b0; - end - else if ( !phy_resetn ) - begin - an_link_up <= 1'b0; - an_duplex <= 1'b0; - an_speed <= SGMII_SPEED_RSVD; - phy_up <= 1'b0; - end - else if ( an_disable ) - begin - phy_up <= 1'b1; - end - // D21.5 is part of config ( M2 has low, M1 has high ) - else if (!rx_k_m1 && !rx_k_m2 && !rx_k_m3 && rx_data_m3 == D21_5 && rx_k_m4 && rx_data_m4 == K28_5 ) - begin - an_link_up <= rx_data_m1[7]; - an_duplex <= rx_data_m1[4]; - an_speed <= rx_data_m1[3:2]; - phy_up <= 1'b0; - end - // IDLE2 1:0xBC, 0:0x50 - else if ( !rx_k_m1 && rx_data_m1 == D16_2 && rx_k_m2 == 1'b1 && rx_data_m2 == K28_5 ) - phy_up <= 1'b1; - - -assign an_ability_detect = (rx_config_cnt == 2'd3 && rx_config_reg != 16'h0000 ); -assign link_timer_pulse = (phy_type == PHY_TYPE_SGMII && pulse_1_6ms) || (phy_type == PHY_TYPE_SX && pulse_10ms); - -endmodule diff --git a/source/bin_to_ascii.v b/source/bin_to_ascii.v deleted file mode 100644 index 12464dc..0000000 --- a/source/bin_to_ascii.v +++ /dev/null @@ -1,128 +0,0 @@ -/* - * bin_to_asc.v - * - * Copyright (C) 2018, 2019 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: Convert binary to ASCII ( 16-bit or 8-bit ) - * - */ - -`timescale 1ns /10ps - -module bin_to_ascii( - input rstn, - input clk, - input width, // 0 for 8-bit, 1 for 16-bit - - // mdio interface - input we_i, // latch the data and start - input [15:0] d_in, // binary in - - // mdio controller interface - output reg run, // block has the output bus - output reg done, // block is done it's processing, use as an internal reset - input busy, // instruct the block to hold off on writing - - // write to output port - output we_o, // asserts we for each ascii word to write out - output reg [6:0] d_out // ascii out -); - - // ascii codes we use - localparam ASCII_ = 7'h5f, - ASCIIq = 7'h3f, - LF = 7'h0a, - CR = 7'h0d; - - - reg [2:0] cnt; // count the nibbles, last two are for CR and LF - reg [3:0] d_bin_in_4; - reg [15:0] d; // internally latched data - - /* start running on we */ - always @(posedge clk or negedge rstn) - begin - if ( !rstn | done ) - run <= 1'b0; - else if ( we_i ) - run <= 1'b1; - end - - /* register the incoming data */ - always @(posedge clk, negedge rstn) - begin - if ( !rstn ) - d <= 16'h0; - else if ( we_i ) - d <= d_in; - end - - /* increment the counter when running, start at 0 or 2 depending on width */ - always @(posedge clk or negedge rstn) - begin - if ( !rstn | done ) - cnt <= 3'd0; - else if ( we_i & ~width ) - cnt <= 3'd2; - else if ( run ) - cnt <= cnt + 1; - end - - always @(posedge clk or negedge rstn) - begin - if ( !rstn ) - done <= 1'b0; - else if ( cnt == 3'd5 ) - done <= 1'b1; - else - done <= 1'b0; - end - - assign we_o = run && ~done; - - /* d_bin_in_4 mux */ - always@(*) - begin - case ( cnt ) - 3'b000: d_bin_in_4 = d[15:12]; - 3'b001: d_bin_in_4 = d[11:8]; - 3'b010: d_bin_in_4 = d[7:4]; - 3'b011: d_bin_in_4 = d[3:0]; - default: d_bin_in_4 = d[3:0]; - endcase - end - - /* perform the conversion */ - always @(*) - begin - d_out = { 3'b011, d_bin_in_4 }; - if ( cnt < 3'd4 && d_bin_in_4 >= 4'd10 ) - case( d_bin_in_4 ) - 4'ha : d_out = 7'h61; - 4'hb : d_out = 7'h62; - 4'hc : d_out = 7'h63; - 4'hd : d_out = 7'h64; - 4'he : d_out = 7'h65; - 4'hf : d_out = 7'h66; - default : d_out = 7'h3f; // question mark - endcase - else if ( cnt == 3'd4 ) - d_out = CR; - else if ( cnt == 3'd5 ) - d_out = LF; - end - -endmodule - diff --git a/source/cam.v b/source/cam.v deleted file mode 100644 index 082194a..0000000 --- a/source/cam.v +++ /dev/null @@ -1,85 +0,0 @@ -/* - * cam.v - * - * Copyright (C) 2018, 2019 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: single cycle, parameterized CAM - * - */ - -`timescale 1ns /10ps - -module cam #(parameter DEPTH = 4, - parameter DEPTHW = 2, - parameter WIDTH = 32) -( - input rstn, - input clk, - - // input for programming - input sel, - input we, - input [DEPTHW+1:0] addr, // add two bits for the byte selects - input [7:0] d_in, - - input search, - input [(WIDTH-1):0]search_address, - - // output - output reg match -); - - reg [(WIDTH-1):0] content[0:DEPTH-1]; - reg [(DEPTH-1):0] valid; - integer i,j; - - // Program the CAM - always @(posedge clk, negedge rstn) - if( !rstn ) begin - for (i=0; i < DEPTH; i=i+1) begin - content[i] <= 32'h0; - valid[i] <= 1'b0; - end - end - else if ( we && sel ) - if (addr[1:0] == 2'b00) begin - content[addr[DEPTHW+1:2]][7:0] <= d_in; - valid[addr[DEPTHW+1:2]] <= 1'b1; - end - else if (addr[1:0] == 2'b01) begin - content[addr[DEPTHW+1:2]][15:8] <= d_in; - valid[addr[DEPTHW+1:2]] <= 1'b1; - end - else if (addr[1:0] == 2'b10) begin - content[addr[DEPTHW+1:2]][23:16] <= d_in; - valid[addr[DEPTHW+1:2]] <= 1'b1; - end - else if (addr[1:0] == 2'b11) begin - content[addr[DEPTHW+1:2]][31:24] <= d_in; - valid[addr[DEPTHW+1:2]] <= 1'b1; - end - - // search the CAM - always @(posedge clk) begin - match <= 1'b0; - for (j=0; j < DEPTH; j=j+1) begin - if (search && valid[j] && search_address == content[j]) - match <= 1'b1; - - end - end - - -endmodule diff --git a/source/clk_gen.v b/source/clk_gen.v deleted file mode 100644 index 9d3e054..0000000 --- a/source/clk_gen.v +++ /dev/null @@ -1,67 +0,0 @@ -/* - * clk_gen.v - * - * Copyright (C) 2018, 2019 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: Generate system / controller clocks from internal oscillator - * - */ - -`timescale 1ns /10ps - -module clk_gen( - input rstn, - output clk_10, - output clk_5, - output clk_2_5, - output clk_1_25, - output clk_slow -); - - - wire clk; - reg [8:0] clk_cnt; - wire clk_0_625, clk_0_3125, clk_75K, clk_37_5K, clk_150K; - - /* - +/- 15% variation in output frequency - 128 is the default for a 2.5 MHz clock, +/- 15% - 32 is 9.7 MHz - 16 for 19.4 MHz. - */ - OSCG oscg_inst(.OSC(clk)); - defparam oscg_inst.DIV = 32; - - always @ (posedge clk or negedge rstn) - begin - if ( !rstn ) - clk_cnt <= 0; - else - clk_cnt <= clk_cnt + 1; - end - - assign clk_10 = clk; // 10 MHz system clock - assign clk_5 = clk_cnt[0]; - assign clk_2_5 = clk_cnt[1]; - assign clk_1_25 = clk_cnt[2]; // 1.22MHz - assign clk_0_625 = clk_cnt[3]; - assign clk_0_3125 = clk_cnt[4]; - assign clk_150K = clk_cnt[5]; - assign clk_75K = clk_cnt[6]; - assign clk_37_5K = clk_cnt[7]; - - assign clk_slow = clk_37_5K; - -endmodule 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 diff --git a/source/directives.v b/source/directives.v deleted file mode 100644 index 5760c23..0000000 --- a/source/directives.v +++ /dev/null @@ -1,34 +0,0 @@ -/* - * directives.v - * - * Copyright (C) 2018, 2019, 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. - * - * Description: misc. directives for board options - * - */ - -// Debug Options for Darsena -//`define DEBUG_I2C -//`define DEBUG_MDIO -//`define DEBUG_SPI -//`define ARD_EXP_UART - -`define DARSENA_V02 -//`define DARSENA_V03 - -// Shield Definition (PORTS 3 & 4) -//`define SHIELD_SMA_SMA -`define SHIELD_GIGE_SMA -//`define SHIELD_SFP_SMA diff --git a/source/dpram.v b/source/dpram.v deleted file mode 100644 index 53c1efc..0000000 --- a/source/dpram.v +++ /dev/null @@ -1,102 +0,0 @@ -/* - * dpram.v - * - * Copyright (C) 2018, 2019 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: DPRAM wrapper - * - */ - -`timescale 1ns /10ps - - -module dpram( - input rstn, - - // port A - input a_clk, - input a_clk_e, - input a_we, - input a_oe, - input [10:0] a_addr, - input [8:0] a_din, - output [8:0] a_dout, - - // port B - input b_clk, - input b_clk_e, - input b_we, - input b_oe, - input [10:0] b_addr, - input [8:0] b_din, - output [8:0] b_dout -); - - -DP16KD dp16kd_inst( - // input data port A - .DIA17( 1'b0 ), .DIA16( 1'b0 ), .DIA15( 1'b0 ), .DIA14( 1'b0 ), .DIA13( 1'b0 ), - .DIA12( 1'b0 ), .DIA11( 1'b0 ), .DIA10( 1'b0 ), .DIA9( 1'b0 ), .DIA8( a_din[8] ), - .DIA7( a_din[7] ), .DIA6( a_din[6] ), .DIA5( a_din[5] ), .DIA4( a_din[4] ), - .DIA3( a_din[3] ), .DIA2( a_din[2] ), .DIA1( a_din[1] ), .DIA0( a_din[0] ), - - // input address bus port A - .ADA13( a_addr[10] ), .ADA12( a_addr[9] ), - .ADA11( a_addr[8] ), .ADA10( a_addr[7]), .ADA9( a_addr[6] ), .ADA8( a_addr[5] ), - .ADA7( a_addr[4] ), .ADA6( a_addr[3] ), .ADA5( a_addr[2] ), .ADA4( a_addr[1] ), .ADA3( a_addr[0] ), - .ADA2( 1'b0 ), .ADA1( 1'b0 ), .ADA0( 1'b0 ), - - .CEA( a_clk_e ), // clock enable - .OCEA( a_oe ), // output clock enable - .CLKA( a_clk ), // clock for port A - .WEA( a_we ), // write enable - .CSA2( 1'b0 ), .CSA1( 1'b0 ), .CSA0( 1'b0 ), // chip selects - .RSTA( ~rstn ), // reset for port A - - // outputs - .DOA17(), .DOA16(), .DOA15(), .DOA14(), .DOA13(), .DOA12(), .DOA11(), .DOA10(), .DOA9( ), - .DOA8( a_dout[8] ), .DOA7( a_dout[7] ), .DOA6( a_dout[6] ), .DOA5( a_dout[5] ), .DOA4( a_dout[4] ), - .DOA3( a_dout[3] ), .DOA2( a_dout[2] ), .DOA1( a_dout[1] ), .DOA0( a_dout[0] ), - - // input data port B - .DIB17( 1'b0 ), .DIB16( 1'b0 ), .DIB15( 1'b0 ), .DIB14( 1'b0 ), .DIB13( 1'b0 ), - .DIB12( 1'b0 ), .DIB11( 1'b0 ), .DIB10( 1'b0 ), .DIB9( 1'b0 ), - .DIB8( b_din[8] ), .DIB7( b_din[7] ), .DIB6( b_din[6] ), .DIB5( b_din[5] ), - .DIB4( b_din[4] ), .DIB3( b_din[3] ), .DIB2( b_din[2] ), .DIB1( b_din[1] ), .DIB0( b_din[0] ), - - // input address bus port B - .ADB13( b_addr[10] ), .ADB12( b_addr[9] ), .ADB11( b_addr[8] ), .ADB10( b_addr[7] ), .ADB9( b_addr[6] ), - .ADB8( b_addr[5] ), .ADB7( b_addr[4] ), .ADB6( b_addr[3] ), .ADB5( b_addr[2] ), - .ADB4( b_addr[1] ), .ADB3( b_addr[0] ), .ADB2( 1'b0 ), .ADB1( 1'b0 ), .ADB0( 1'b0 ), - - .CEB( b_clk_e ), // clock enable - .OCEB( b_oe ), // output clock enable - .CLKB( b_clk ), // clock for port B - .WEB( b_we ), // write enable - .CSB2( 1'b0 ), .CSB1( 1'b0 ), .CSB0( 1'b0 ), // chip selects - .RSTB( ~rstn ), // reset for port B - - // outputs - - .DOB17(), .DOB16(), .DOB15(), .DOB14(), .DOB13(), .DOB12(), .DOB11(), .DOB10(), .DOB9( ), - .DOB8( b_dout[8] ), .DOB7( b_dout[7] ), .DOB6( b_dout[6] ), .DOB5( b_dout[5] ), - .DOB4( b_dout[4] ), .DOB3( b_dout[3] ), .DOB2( b_dout[2] ), .DOB1( b_dout[1] ), .DOB0( b_dout[0] ) - -); -// defparam dp16kd_inst.INITVAL_00 = "0x123456789abcdef0123456789abcdef0123456789abcdef0123456789abcaa9980123456789abcde"; -defparam dp16kd_inst.DATA_WIDTH_A = 9; -defparam dp16kd_inst.DATA_WIDTH_B = 9; - -endmodule diff --git a/source/drop_fifo.v b/source/drop_fifo.v deleted file mode 100644 index 736947c..0000000 --- a/source/drop_fifo.v +++ /dev/null @@ -1,176 +0,0 @@ -/* - * drop_fifo.v - * - * Copyright 2018, 2019, 2020, 2021 Mind Chasers Inc. - * Copyright 2023 Private Island Networks 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: FIFO that supports dropping data if not kept - * - * For more information, see https://privateisland.tech/dev/pi-doc - * - */ - -module drop_fifo( - input rstn, - input clk, - input passthrough, // don't store / delay data, write through instead - input enable, // enable the FIFO - input keep, // this packet won't be dropped, start transferring it (writer must be sure FIFO won't run dry during writes) - - // input data - input we_in, - input [8:0] d_in, - input wr_done, // keep should occur before wr_done is asserted. - input rx_eop, - - // output data - output reg we_out, - output reg [8:0] d_out, - - // debug - output reg active -); - -// local parameters and includes - - -// nets and registers -reg [10:0] wr_ptr0, wr_ptr1; // wr_ptr0 is updated on each write; wr_ptr1 is updated at end of packet -reg [10:0] rd_ptr; -wire [8:0] d_out_internal; -reg read_run, read_run_m1, read_run_m2; // read continues while read_run is set -reg kept; -wire fifo_empty; - -/* - * kept: assert for length of write duration after keep asserts (when enable is active) - */ -always @(posedge clk, negedge rstn) - if( !rstn ) - kept <= 1'b0; - else if ( wr_done ) - kept <= 1'b0; - else if ( keep && enable ) - kept <= 1'b1; - -/* - * wr_ptr0 logic - */ -always @(posedge clk, negedge rstn) - if( !rstn ) - wr_ptr0 <= 'd0; - else if ( we_in ) - wr_ptr0 <= wr_ptr0 + 1'b1; - -/* - * wr_ptr1 logic - * sync pointers at end of rx packet for next packet -*/ -always @(posedge clk, negedge rstn) - if( !rstn ) - wr_ptr1 <= 'd0; - else if ( wr_done ) - wr_ptr1 <= wr_ptr0 +1; // a write takes place with wr_done - -/* - * read_run logic - * continues until the FIFO is empty - */ -always @(posedge clk, negedge rstn) - if( !rstn ) - read_run <= 1'b0; - else if (kept && wr_done) - read_run <= 1'b1; - else if ( fifo_empty ) - read_run <= 1'b0; - - -always @(posedge clk, negedge rstn) - if( !rstn ) - read_run_m1 <= 1'b0; - else - read_run_m1 <= read_run; - - -always @(posedge clk, negedge rstn) - if( !rstn ) - read_run_m2 <= 1'b0; - else - read_run_m2 <= read_run_m1; - -/* -* rd_ptr logic -*/ -always @(posedge clk, negedge rstn) - if( !rstn ) - rd_ptr <= 'd0; - else if (kept && wr_done) - rd_ptr <= wr_ptr1; // set rd_ptr to the beginning of where the write started - else if (read_run && !fifo_empty) - rd_ptr <= rd_ptr+ 1'b1; - -/* - * we_out logic - */ -always @(posedge clk, negedge rstn) - if( !rstn ) - we_out <= 1'b0; - else if ( read_run_m1 && read_run_m2 ) - we_out <= 1'b1; - else - we_out <= 1'b0; - -assign fifo_empty = (wr_ptr1 == rd_ptr); - -/* - * d_out register - * - */ -always @(posedge clk, negedge rstn) - if( !rstn ) - d_out <= 'd0; - else - d_out <= d_out_internal; - - -always @(posedge clk, negedge rstn) - if( !rstn ) - active <= 1'b0; - else if ( we_in || we_out ) - active <= 1'b1; - else - active <= 1'b0; - -dpram dpram_fifo( -.rstn( rstn ), -.a_clk( clk ), -.a_clk_e( 1'b1 ), -.a_we( we_in ), -.a_oe( 1'b0 ), -.a_addr( wr_ptr0 ), -.a_din( d_in ), -.a_dout( ), -// port B -.b_clk( clk ), -.b_clk_e( read_run ), -.b_we( 1'b0 ), -.b_oe( 1'b1 ), -.b_addr( rd_ptr ), -.b_din( 9'h0 ), -.b_dout( d_out_internal ) -); - - -endmodule diff --git a/source/ethernet_params.v b/source/ethernet_params.v deleted file mode 100644 index dcb7dba..0000000 --- a/source/ethernet_params.v +++ /dev/null @@ -1,39 +0,0 @@ -/* - * ethernet_params.v - * - * Copyright (C) 2018, 2019, 2020 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: Ethernet related parameters - * - */ - - -localparam MTU = 1520; // Ethernet is actually 1500+framing (max 18) -localparam IPG = 96; // Inter-packet Gap Bits - -localparam SZ_ETH_HEADER = 14; // w/o VLAN -localparam SZ_IPV4_HEADER = 20; // w/o Options -localparam SZ_UDP_HEADER = 8; - -localparam TX_MODE_AN = 3'b000, -TX_MODE_IDLE = 3'b001, -TX_MODE_XMT_PKT = 3'b010, // anything >= to this is a mode where a packet is transmitted -TX_MODE_XMT_METRICS = 3'b011, -TX_MODE_XMT_CUSTOM = 3'b100; - -// Note: The Length/Type field is transmitted and received with the high order octet first. -localparam ETHER_TYPE_IPV4 = 16'h0800, -ETHER_TYPE_IPV6 = 16'h86DD, -ETHER_TYPE_ARP = 16'h0806; diff --git a/source/fcs.v b/source/fcs.v deleted file mode 100644 index 6abf536..0000000 --- a/source/fcs.v +++ /dev/null @@ -1,142 +0,0 @@ -/* - * fcs.v - * - * Copyright (C) 2018, 2019 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: FCS checksum - * - * - */ -`timescale 1ns /10ps - -//////////////////////////////////////////////////////////////////////////////// -// Copyright (C) 1999-2008 Easics NV. -// This source file may be used and distributed without restriction -// provided that this copyright statement is not removed from the file -// and that any derivative work contains the original copyright notice -// and the associated disclaimer. -// -// THIS SOURCE FILE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS -// OR IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED -// WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// Purpose : synthesizable CRC function -// * polynomial: x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1 -// * data width: 8 -// -// Info : tools@easics.be -// http://www.easics.com -//////////////////////////////////////////////////////////////////////////////// - -/* -* a) The first 32 bits of the frame are complemented. -* b) The n bits of the MAC frame considered to be the coefficients of a polynomial M(x) of degree n � 1. -* The first bit of the Destination Address field corresponds to the x(n�1) term -* and the last bit of the MAC Client Data field (or Pad field if present) corresponds to the x0 term. -* c) M(x) is multiplied by x**32 and divided by G(x), producing a remainder R(x) of degree = 31. -* d) The coefficients of R(x) are considered to be a 32-bit sequence. -* e) The bit sequence is complemented and the result is the CRC. -* f) FCS should be trnansmitted msbit first ( opposite of the rest of MAC frame ) -*/ -module fcs( - input rstn, - input clk, - - // control interface - input init, - input enable, - - // addr & data - input [1:0] addr, - input [0:7] din, - output [7:0] dout -); - - -reg [31:0] crc; -reg [7:0] d; - -assign dout = ~{ d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7] }; - -always @(*) - begin - case(addr) - 2'b00: d <= crc[31:24]; - 2'b01: d <= crc[23:16]; - 2'b10: d <= crc[15:8]; - 2'b11: d <= crc[7:0]; - endcase - end - -always @(posedge clk or negedge rstn) - if(!rstn) - crc <= 32'hffffffff; - else if (init) - crc <= 32'hffffffff; - else if (enable) - crc <= nextCRC32_D8(din,crc); - -// {d[0],d[1],d[2],d[3],d[4],d[5],d[6],d[7]} - - // polynomial: x^32 + x^26 + x^23 + x^22 + x^16 + x^12 + x^11 + x^10 + x^8 + x^7 + x^5 + x^4 + x^2 + x^1 + 1 - // data width: 8 - // convention: the first serial bit is D[7] - function [31:0] nextCRC32_D8; - - input [0:7] Data; - input [31:0] crc; - reg [0:7] d; - reg [31:0] c; - reg [31:0] newcrc; - begin - d = Data; - c = crc; - - newcrc[0] = d[6] ^ d[0] ^ c[24] ^ c[30]; - newcrc[1] = d[7] ^ d[6] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[30] ^ c[31]; - newcrc[2] = d[7] ^ d[6] ^ d[2] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[26] ^ c[30] ^ c[31]; - newcrc[3] = d[7] ^ d[3] ^ d[2] ^ d[1] ^ c[25] ^ c[26] ^ c[27] ^ c[31]; - newcrc[4] = d[6] ^ d[4] ^ d[3] ^ d[2] ^ d[0] ^ c[24] ^ c[26] ^ c[27] ^ c[28] ^ c[30]; - newcrc[5] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[24] ^ c[25] ^ c[27] ^ c[28] ^ c[29] ^ c[30] ^ c[31]; - newcrc[6] = d[7] ^ d[6] ^ d[5] ^ d[4] ^ d[2] ^ d[1] ^ c[25] ^ c[26] ^ c[28] ^ c[29] ^ c[30] ^ c[31]; - newcrc[7] = d[7] ^ d[5] ^ d[3] ^ d[2] ^ d[0] ^ c[24] ^ c[26] ^ c[27] ^ c[29] ^ c[31]; - newcrc[8] = d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[0] ^ c[24] ^ c[25] ^ c[27] ^ c[28]; - newcrc[9] = d[5] ^ d[4] ^ d[2] ^ d[1] ^ c[1] ^ c[25] ^ c[26] ^ c[28] ^ c[29]; - newcrc[10] = d[5] ^ d[3] ^ d[2] ^ d[0] ^ c[2] ^ c[24] ^ c[26] ^ c[27] ^ c[29]; - newcrc[11] = d[4] ^ d[3] ^ d[1] ^ d[0] ^ c[3] ^ c[24] ^ c[25] ^ c[27] ^ c[28]; - newcrc[12] = d[6] ^ d[5] ^ d[4] ^ d[2] ^ d[1] ^ d[0] ^ c[4] ^ c[24] ^ c[25] ^ c[26] ^ c[28] ^ c[29] ^ c[30]; - newcrc[13] = d[7] ^ d[6] ^ d[5] ^ d[3] ^ d[2] ^ d[1] ^ c[5] ^ c[25] ^ c[26] ^ c[27] ^ c[29] ^ c[30] ^ c[31]; - newcrc[14] = d[7] ^ d[6] ^ d[4] ^ d[3] ^ d[2] ^ c[6] ^ c[26] ^ c[27] ^ c[28] ^ c[30] ^ c[31]; - newcrc[15] = d[7] ^ d[5] ^ d[4] ^ d[3] ^ c[7] ^ c[27] ^ c[28] ^ c[29] ^ c[31]; - newcrc[16] = d[5] ^ d[4] ^ d[0] ^ c[8] ^ c[24] ^ c[28] ^ c[29]; - newcrc[17] = d[6] ^ d[5] ^ d[1] ^ c[9] ^ c[25] ^ c[29] ^ c[30]; - newcrc[18] = d[7] ^ d[6] ^ d[2] ^ c[10] ^ c[26] ^ c[30] ^ c[31]; - newcrc[19] = d[7] ^ d[3] ^ c[11] ^ c[27] ^ c[31]; - newcrc[20] = d[4] ^ c[12] ^ c[28]; - newcrc[21] = d[5] ^ c[13] ^ c[29]; - newcrc[22] = d[0] ^ c[14] ^ c[24]; - newcrc[23] = d[6] ^ d[1] ^ d[0] ^ c[15] ^ c[24] ^ c[25] ^ c[30]; - newcrc[24] = d[7] ^ d[2] ^ d[1] ^ c[16] ^ c[25] ^ c[26] ^ c[31]; - newcrc[25] = d[3] ^ d[2] ^ c[17] ^ c[26] ^ c[27]; - newcrc[26] = d[6] ^ d[4] ^ d[3] ^ d[0] ^ c[18] ^ c[24] ^ c[27] ^ c[28] ^ c[30]; - newcrc[27] = d[7] ^ d[5] ^ d[4] ^ d[1] ^ c[19] ^ c[25] ^ c[28] ^ c[29] ^ c[31]; - newcrc[28] = d[6] ^ d[5] ^ d[2] ^ c[20] ^ c[26] ^ c[29] ^ c[30]; - newcrc[29] = d[7] ^ d[6] ^ d[3] ^ c[21] ^ c[27] ^ c[30] ^ c[31]; - newcrc[30] = d[7] ^ d[4] ^ c[22] ^ c[28] ^ c[31]; - newcrc[31] = d[5] ^ c[23] ^ c[29]; - nextCRC32_D8 = newcrc; - end - endfunction -endmodule diff --git a/source/half_fifo.v b/source/half_fifo.v deleted file mode 100644 index e18f543..0000000 --- a/source/half_fifo.v +++ /dev/null @@ -1,194 +0,0 @@ -/* - * half_fifo.v - * - * Copyright (C) 2018, 2019 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: micro / FIFO interface - * - */ - -`timescale 1ns /10ps - -module half_fifo #(parameter DATA_WIDTH = 9, DPRAM_DEPTH=11 ) -( - input rstn, - input uc_clk, - input fifo_clk, - - // UC interrupt support - output reg fifo_we_int, - - // tx_mode - input tx_mode, - - // UC side: common DPRAM signals for RX and TX - input [DPRAM_DEPTH-1:0] dpram_addr, - input [DATA_WIDTH-1:0] dpram_din, - output reg [DATA_WIDTH-1:0] dpram_dout, - input dpram_we, - input dpram_oe, - // UC select signals - input dpram_ptrs_sel, - input dpram_rx_sel, - input dpram_tx_sel, - - // FIFO TX (input) - input fifo_we, - input [DATA_WIDTH-1:0] fifo_d_in, - - // FIFO RX (output) - input fifo_re, - output [DATA_WIDTH-1:0] fifo_d_out, - - // FIFO flags - output rx_empty, // dpram 0 (reader) - output tx_full - -); - -/* - * Pointers for accessing memory. - * UC writes RX and reads TX - * Switch writes (via FIFO I/F) TX and reads RX - */ -reg [DPRAM_DEPTH-1:0] rx_wr_ptr; -reg [DPRAM_DEPTH-1:0] rx_rd_ptr; - -reg [DPRAM_DEPTH-1:0] tx_wr_ptr; -reg [DPRAM_DEPTH-1:0] tx_rd_ptr; - -reg fifo_we_m1; - -reg reset_ptrs; -wire [DATA_WIDTH-1:0] dpram_rx_dout, dpram_tx_dout; - -/* read data mux */ -always @(*) - casez({ dpram_rx_sel, dpram_tx_sel, dpram_ptrs_sel, dpram_addr[2:0] } ) - 6'b001000: dpram_dout = rx_wr_ptr; - 6'b001001: dpram_dout = rx_rd_ptr; - 6'b001010: dpram_dout = tx_wr_ptr; - 6'b001011: dpram_dout = tx_rd_ptr; - 6'b001100: dpram_dout = reset_ptrs; - 6'b010???: dpram_dout = dpram_tx_dout; - 6'b100???: dpram_dout = dpram_rx_dout; - default: dpram_dout = dpram_tx_dout; - endcase - -always @(posedge uc_clk, negedge rstn) - if ( !rstn ) - reset_ptrs <= 1'b0; - else if ( dpram_ptrs_sel && dpram_we && dpram_addr[2:0] == 3'h4 ) - reset_ptrs <= dpram_din[0]; - -/* RX wr ptr (UC writes) */ -always @(posedge uc_clk, negedge rstn) - if ( !rstn ) - rx_wr_ptr <= 'h0; - else if ( reset_ptrs ) - rx_wr_ptr <= 'h0; - else if ( dpram_ptrs_sel && dpram_we && dpram_addr[2:0] == 3'h0 ) - rx_wr_ptr <= dpram_din; - -/* TX rd ptr (uP reads) */ -always @(posedge uc_clk, negedge rstn) - if ( !rstn ) - tx_rd_ptr <= 'h0; - else if ( reset_ptrs ) - tx_rd_ptr <= 'h0; - else if ( dpram_ptrs_sel && dpram_we && dpram_addr[2:0] == 3'h3 ) - tx_rd_ptr <= dpram_din; - -/* RX rd ptr (switch reads via FIFO), auto increment */ -always @(posedge fifo_clk, negedge rstn) - if( !rstn ) - rx_rd_ptr <= 'd0; - else if ( reset_ptrs ) - rx_rd_ptr <= 'd0; - else if ( fifo_re && !rx_empty ) // advance the pointer if FIFO isn't empty - rx_rd_ptr <= rx_rd_ptr + 1; - - /* TX wr ptr (switch writes via FIFO) */ -always @(posedge fifo_clk, negedge rstn) - if( !rstn ) - tx_wr_ptr <= 'd0; - else if ( reset_ptrs ) - tx_wr_ptr <= 'd0; - else if ( fifo_we ) - tx_wr_ptr <= tx_wr_ptr + 1; - - -assign rx_empty = (rx_rd_ptr == rx_wr_ptr) ? 1'b1 : 1'b0; -assign tx_full = (tx_rd_ptr != tx_wr_ptr) ? 1'b1 : 1'b0; - - - -/* Assert interrupt whenever fifo_we is negated ( writing is done ) */ -always @(posedge fifo_clk, negedge rstn) - if ( !rstn ) - fifo_we_m1 <= 1'b0; - else - fifo_we_m1 <= fifo_we; - - -always @(posedge fifo_clk, negedge rstn) - if ( !rstn ) - fifo_we_int <= 1'b0; - else if ( !fifo_we & fifo_we_m1 ) - fifo_we_int <= 1'b1; - else - fifo_we_int <= 1'b0; - - -/* micro uses A side, FIFO uses B side */ -dpram dpram_rx( - .rstn( rstn ), - .a_clk( uc_clk ), - .a_clk_e( dpram_rx_sel ), - .a_we( dpram_we ), - .a_oe( 1'b1 ), - .a_addr( { 2'b00, dpram_addr } ), - .a_din( dpram_din ), - .a_dout( dpram_rx_dout ), - // port B - .b_clk( fifo_clk ), - .b_clk_e( 1'b1 ), - .b_we( 1'b0 ), - .b_oe( fifo_re ), - .b_addr( { 2'b00, rx_rd_ptr } ), - .b_din( 9'h0 ), - .b_dout( fifo_d_out ) -); - -dpram dpram_tx( - .rstn( rstn ), - .a_clk( uc_clk ), - .a_clk_e( dpram_tx_sel ), - .a_we( dpram_we ), - .a_oe( 1'b1 ), - .a_addr( { 2'b00, dpram_addr } ), - .a_din( dpram_din ), - .a_dout( dpram_tx_dout ), - // port B - .b_clk( fifo_clk ), - .b_clk_e( 1'b1 ), - .b_we( fifo_we ), - .b_oe( 1'b0 ), - .b_addr( { 2'b00, tx_wr_ptr } ), - .b_din( fifo_d_in ), - .b_dout( ) -); - -endmodule diff --git a/source/i2c.v b/source/i2c.v deleted file mode 100644 index aca6452..0000000 --- a/source/i2c.v +++ /dev/null @@ -1,391 +0,0 @@ -/* - * i2c.v - * - * Copyright (C) 2018, 2019 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: I2C slave controller for communicating with internal controller - * - */ - - -`timescale 1ns /10ps - - -module i2c( - input rstn, - input clk, - - // external I2C I/O - input scl_i, // serial clock - output scl_o, // serial clock out - output scl_oe, // serial clock output enable - - input sda_i, // serial data in - output reg sda_o, // serial data out - output reg sda_oe, // serial data output enable - - // shared memory and controller data output - output [7:0] mem_do, - - // dedicated memory interface - output [10:0] mem_ad, - output mem_ce, - output reg mem_we, - input [7:0] mem_di, - - // dedicated controller write interface - output reg cont_we, - output cont_done, - - // Controller->FIFO input interface - input tx_fifo_empty, // use for control and pass as msbit of data - input [6:0] fifo_di, // data from FIFO to transmit on I2C - output reg fifo_re - -); - -localparam CONT_SEL = 7'h10, - DPRAM_SEL = 7'h20, - SCI_SEL = 7'h30; - -// slave-related signals - -reg scl_high, scl_low; -reg [4:0] bit_cnt; // cnt the bits received -reg start; // falling SDA while SCL is high -reg stop; // rising SDA while SCL is high -reg run; // assert while running and counting bits -reg rwn; // follows address - -reg [6:0] dev_ad; // 7-bit device address -reg [7:0] addr; // address -reg [7:0] d; // data received from external i2c controller during an I2C write -wire target_sel, dpram_sel, cont_sel; -reg scl_i_m1, scl_i_m2, sda_i_m1; // delayed versions of the inputs -reg ack; - -wire [7:0] i_di; // internal data in muxed from external sources (e.g., DPRAM and controller) - -assign i_di = dpram_sel ? mem_di : { tx_fifo_empty, fifo_di }; - -// master-related signals -//reg halt; // assert if we lose arbitration, detect a zero in place of a one - -assign scl_oe = 1'b0; - -// since it's open drain, never drive the outputs high -assign scl_o = 1'b0; - -// slave interface - -/* - debounce and capture the asynch inputs - delayed signals, by default, they're 1 since they're open drain -*/ -always @(posedge clk or negedge rstn) - begin - if (!rstn) - begin - scl_i_m1 <= 1'b1; - scl_i_m2 <= 1'b1; - sda_i_m1 <= 1'b1; - end - else - begin - scl_i_m1 <= scl_i; - scl_i_m2 <= scl_i_m1; - sda_i_m1 <= sda_i; - end - end - -/* - create a one shot when scl is first stable high - use this to register inputs -*/ -always@(posedge clk or negedge rstn) - begin - if (!rstn) - scl_high <= 1'b0; - else if (scl_i && scl_i_m1 && ~scl_i_m2) - scl_high <= 1'b1; - else - scl_high <= 1'b0; - end - -/* - create a one shot when scl is first stable low - use this to register outputs -*/ -always@(posedge clk or negedge rstn) - begin - if (!rstn) - scl_low <= 1'b0; - else if ( !scl_i && !scl_i_m1 && scl_i_m2) - scl_low <= 1'b1; - else - scl_low <= 1'b0; - end - -/* - one shot start/restart bit, sda 1 to 0 anytime while scl is high -*/ -always @(posedge clk or negedge rstn) - begin - if (!rstn) - start <= 1'b0; - else if ( scl_i == 1'b1 && scl_i_m1 == 1'b1 && sda_i == 1'b0 && sda_i_m1 == 1'b1 ) - start <= 1'b1; - else - start <= 1'b0; - end - -/* - one shot stop bit, sda 0 to 1 anytime while scl is high -*/ -assign cont_done = stop & ~rwn; - -always @(posedge clk or negedge rstn) - begin - if (!rstn ) - stop <= 1'b0; - else if ( scl_i == 1'b1 && scl_i_m1 == 1'b1 && sda_i == 1'b1 && sda_i_m1 == 1'b0 ) - stop <= 1'b1; - else - stop <= 1'b0; - end - -/* - This I2C block runs between start and stop while run == 1 -*/ -always @(posedge clk or negedge rstn) - begin - if (!rstn) - run <= 1'b0; - else if ( start ) - run <= 1'b1; - else if ( stop ) - run <= 1'b0; - end - - -/* - bit_cnt indicates the state of the i2c transfer: - start/stop act as synchronous resets - otherwise, bit_cnt can change when scl is low - - 31 (1F): reserved for first cycle after start / idle state - 0:6: dev_ad - 7: rwn, ACK is clocked out - 8: - 9:16: if rwn == 0 addr, else d, ACK is clocked out on 16 - 17: ( restart to 9 if read ) - 18:25: write data, ack write data is clocked out on 25 - 26: ( restart to 18 for write data ) -*/ -always @(posedge clk or negedge rstn) - begin - if ( !rstn ) - bit_cnt <= 5'h1f; - else if ( start || stop ) - bit_cnt <= 5'h1f; - else if ( run && scl_low ) - begin - if ( rwn && bit_cnt == 5'd17 ) - bit_cnt <= 5'd9; - else if ( bit_cnt == 5'd26 ) - bit_cnt <= 5'd18; - else - bit_cnt <= bit_cnt + 1; - end - end - -/* - shift device address (dev_ad) into the module from the i2c bus -*/ -always @(posedge clk or negedge rstn) - begin - if ( !rstn ) - dev_ad <= 7'h0; - else if ( stop ) - dev_ad <= 7'h0; - else if ( run && scl_high && bit_cnt <= 5'h6 ) - dev_ad <= { dev_ad[5:0], sda_i }; - end - - -/* - shift I2C memory addr into the module from the i2c bus during first cycle - auto increment on subsequent byte reads during same I2C cycle -*/ -always @(posedge clk or negedge rstn) - begin - if (!rstn) - addr <= 8'h00; - else if ( run && scl_high) - begin - if ( !rwn && bit_cnt >= 5'd9 && bit_cnt <= 5'd16 ) - addr <= { addr[6:0], sda_i }; - else if ( (rwn && bit_cnt == 5'd17) || (!rwn && bit_cnt == 5'd26) ) - addr <= addr + 1; - end - end - - -/* -* shift write data (d) into the module from the i2c bus. -*/ -always @(posedge clk or negedge rstn) - begin - if (!rstn) - d <= 8'ha5; - else if ( run && scl_high && !rwn && !start && bit_cnt >= 5'd18 && bit_cnt < 5'd26 ) - d <= { d[6:0], sda_i }; - end - - - -assign dpram_sel = ( dev_ad == DPRAM_SEL ) ? 1 : 0; -assign cont_sel = ( dev_ad == CONT_SEL ) ? 1 : 0; -assign target_sel = cont_sel | dpram_sel; - -/* - register ack during I2C reads when bit_cnt == 17 -*/ -always @(posedge clk or negedge rstn) - begin - if ( !rstn ) - ack <= 1'b0; - else if ( run && scl_high && rwn && bit_cnt == 5'd17 ) - ack <= ~sda_i; - end - -/* - register rwn bit -*/ -always @(posedge clk or negedge rstn) - begin - if ( !rstn ) - rwn <= 1'b1; - else if ( stop ) - rwn <= 1'b1; - else if ( run && scl_high && bit_cnt == 5'd7 ) - rwn <= sda_i; - end - -/* - sda_oe logic, note that the bit_cnt will be changing simultaneously, so it's one behind -*/ -always @(posedge clk or negedge rstn) - begin - if ( !rstn ) - begin - sda_oe <= 1'b0; - sda_o <= 1'b1; - end - else if ( stop ) - begin - sda_oe <= 1'b0; - sda_o <= 1'b1; - end - else if ( scl_low ) - begin - // ack the first byte written by master if it's addressed to our I2C slave - if ( target_sel && bit_cnt == 5'd7 ) - begin - sda_oe <= 1'b1; - sda_o <= 1'b0; - end - // ack write address - else if ( target_sel && rwn == 1'b0 && bit_cnt == 5'd16 ) - begin - sda_oe <= 1'b1; - sda_o <= 1'b0; - end - // ack write data - else if ( target_sel && rwn == 1'b0 && bit_cnt == 5'd25 ) - begin - sda_oe <= 1'b1; - sda_o <= 1'b0; - end - // drive read data - else if ( target_sel && rwn == 1'b1 && bit_cnt >= 5'd8 && bit_cnt <=5'd15 ) // xmt data for read cycle - begin - sda_oe <= 1'b1; - sda_o <= i_di[7-bit_cnt[2:0]]; - end - // drive data for first bit of burst read cycle, multi-byte if we get an ack - // if no ack, then the burst read or single read is done - else if ( target_sel && rwn == 1'b1 && ack && bit_cnt == 5'd17 ) - begin - sda_oe <= 1'b1; - sda_o <= i_di[7]; - end - else - begin - sda_oe <= 1'b0; - sda_o <= 1'b1; // don't care - end - end - end - -/* DPRAM Control */ -assign mem_ad = {3'b0, addr}; -assign mem_ce = 1'b1; - -/* - driver: mem_do - shared between both cont and dpram interfaces - drive addr for first byte since this is the controller cmd -*/ -assign mem_do = ( bit_cnt <= 5'd17 ) ? addr : d; - -// mem_we bit -always @(posedge clk or negedge rstn) - begin - if ( !rstn ) - mem_we <= 1'b0; - else if ( run && scl_high && dpram_sel && !rwn && bit_cnt == 5'd26 ) - mem_we <= 1'b1; - else - mem_we <= 1'b0; - end - -// cont_we bit is asserted at the end of both command and data bytes -always @(posedge clk or negedge rstn) - begin - if ( !rstn ) - cont_we <= 1'b0; - else if ( run && scl_high && cont_sel && !rwn && (bit_cnt == 5'd26 || bit_cnt == 5'd17) ) - cont_we <= 1'b1; - else - cont_we <= 1'b0; - end - -/* -* drive: fifo_re -* Stop asserting during a burst if we don't get an ACK (use sda_i for real-time ACK) -*/ -always @(posedge clk or negedge rstn) - begin - if ( !rstn ) - fifo_re <= 1'b0; - else if ( run && scl_high && cont_sel && rwn && !tx_fifo_empty && ( bit_cnt == 5'd8 || ( bit_cnt == 5'd17 && !sda_i ) ) ) - fifo_re <= 1'b1; - else - fifo_re <= 1'b0; - end - - -endmodule diff --git a/source/interrupts.v b/source/interrupts.v deleted file mode 100644 index c77dfb7..0000000 --- a/source/interrupts.v +++ /dev/null @@ -1,77 +0,0 @@ -/* - * interrupts.v - * - * Copyright (C) 2018, 2019 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: uC Interrupt Controller - * - */ - -`timescale 1ns /10ps - - -module interrupts ( - input rstn, - input clk, - input uc_clk, - - -// uC interface - input sel, - input we, - input addr, - input [6:0] d_in, - output [6:0] d_out, - - // interrupt sources - input cont_int, - input [3:0] phy_int, - input [3:0] mac_int, - - // int out - output int_o -); - -localparam INT_CONTROLLER = 'h01, - INT_PHY0 = 'h02, - INT_PHY1 = 'h04, - INT_MAC0 = 'h08, - INT_MAC1 = 'h10, - INT_MAC2 = 'h20, - INT_MAC3 = 'h40; - -reg [6:0] int_enable; -reg [6:0] int_src; - -assign d_out = addr ? int_src : int_enable; -assign int_o = int_src[6] & int_enable[6] | int_src[5] & int_enable[5] | int_src[4] & int_enable[4] | int_src[3] & int_enable[3] | - int_src[2] & int_enable[2] | int_src[1] & int_enable[1] | int_src[0] & int_enable[0]; - -always @(posedge uc_clk or negedge rstn) - if (!rstn) - int_enable <= INT_MAC2 | INT_MAC3; - else if (sel && we && !addr) - int_enable <= d_in; - -always @(posedge uc_clk or negedge rstn) - if (!rstn) - int_src <= 7'h0; - else if (sel && we && addr) - int_src <= d_in; - else - int_src <= int_src | { mac_int, phy_int[1:0], cont_int }; - - -endmodule diff --git a/source/ipv4.v b/source/ipv4.v deleted file mode 100644 index 55ab7a7..0000000 --- a/source/ipv4.v +++ /dev/null @@ -1,152 +0,0 @@ -/* - * ipv4.v - * - * Copyright (C) 2018, 2019 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: Receive State Machine and Logic for IPv4 - * - * - * 0-7 8-15 16-23 24-31 - * 0 Version/IHL TOS Total Length............. - * 4 Identification...... Flags/Frag Off........... - * 8 TTL Protocol Header Checksum.......... - * 12 Source IP Address.................................... - * 16 Dest IP Address...................................... - * 20 Options / Padding.................................... - * - * - * When pkt_start is detected, rx_data_m2 has the first byte - */ - -`timescale 1ns /10ps - -module ipv4_rx ( - input rstn, - input clk, - - // control - input phy_resetn, - input phy_up, - - // packet data - input pkt_start, // assert for each new frame to start state machines - input rx_eop, // use as a synch reset - input[7:0] rx_data_m1, - input[7:0] rx_data_m2, - input[7:0] rx_data_m3, // first byte of packet appears here simultaneous with pkt_start - input[7:0] rx_data_m4, - - // flags - output pkt_complete, - output reg trigger_src_addr, - output reg trigger_dst_addr, - output reg keep - ); - - /* Byte Address (when last byte of field is present on rx_data_m1 ) */ - localparam IPV4_TOS=1, IPV4_LENGTH=3, IPV4_IP_ID=5, IPV4_PROTOCOL=9, - IPV4_HDR_CKSUM=11, IPV4_SRC_ADDR=15, IPV4_DST_ADDR=19; - - localparam RX_ST_IDLE=4'h0, RX_ST_DATA=4'h1, RX_ST_DONE=4'h2, RX_ST_3=4'h3, - RX_ST_4=4'h4, RX_ST_5=4'h5, RX_ST_6=4'h6, RX_ST_7=4'h7, - RX_ST_8=4'h8, RX_ST_9=4'h9, RX_ST_A=4'ha, RX_ST_B=4'hb, - RX_ST_C=4'hc, RX_ST_D=4'hd, RX_ST_E=4'he, RX_ST_F=4'hf; - - localparam IPV4_PROTO_ICMP = 1, IPV4_PROTO_IGMP = 2, IPV4_PROTO_TCP = 6, IPV4_PROTO_UDP = 17, - IPV4_PROTO_ENCAP = 41, IPV4_PROTO_OSPF = 89, IPV4_PROTO_SCTP = 132; - - - reg [3:0] rx_state; - reg [10:0] rx_byte_cnt; - reg [10:0] rx_pkt_length; - reg [7:0] protocol; - wire rx_error; - - /* - * rx_state machine - * capture an IPv4 Packet - * - */ - always @(posedge clk, negedge rstn) - if (!rstn) - rx_state <= RX_ST_IDLE; - else if ( rx_eop || !phy_resetn ) // EOP will reset state machine - rx_state <= RX_ST_IDLE; - else if ( phy_up ) - case ( rx_state ) - RX_ST_IDLE: if ( pkt_start ) // Found /S/ - rx_state <= RX_ST_DATA; - RX_ST_DATA: if (pkt_complete) - rx_state <= RX_ST_DONE; - RX_ST_DONE: rx_state <= RX_ST_IDLE; - endcase - else - rx_state <= RX_ST_IDLE; - - - /* rx_byte_cnt */ - always @(posedge clk, negedge rstn) - if (!rstn) - rx_byte_cnt <= 0; - else if ( rx_state == RX_ST_IDLE && !pkt_start ) // synch reset - rx_byte_cnt <= 1; - else if ( rx_state != RX_ST_IDLE || pkt_start ) - rx_byte_cnt <= rx_byte_cnt + 1; - - - /* protocol */ - always @(posedge clk, negedge rstn) - if ( !rstn ) - protocol <= 0; - else if ( rx_eop ) - protocol <= 0; - else if ( rx_byte_cnt == IPV4_PROTOCOL ) - protocol <= rx_data_m1; - - - /* rx_pkt_length */ - always @(posedge clk, negedge rstn) - if ( !rstn ) - rx_pkt_length <= 11'h7ff; - else if ( rx_eop ) - rx_pkt_length <= 11'h7ff; - else if ( rx_state == RX_ST_DATA && rx_byte_cnt == IPV4_LENGTH ) - rx_pkt_length <= { rx_data_m2[2:0], rx_data_m1 }; - - /* - * Packet Filter Trigger(s), assert the sample before the data appears - * - */ - always @(posedge clk, negedge rstn) - if (!rstn) - trigger_src_addr <= 1'b0; - else if ( rx_byte_cnt == IPV4_SRC_ADDR-1 ) - trigger_src_addr <= 1'b1; - else - trigger_src_addr <= 1'b0; - - always @(posedge clk, negedge rstn) - if (!rstn) - trigger_dst_addr <= 1'b0; - else if ( rx_byte_cnt == IPV4_DST_ADDR-1 ) - trigger_dst_addr <= 1'b1; - else - trigger_dst_addr <= 1'b0; - - assign pkt_complete = ( rx_state >= RX_ST_DATA && rx_pkt_length == rx_byte_cnt+1 ) ? 1 : 0; - assign rx_error = 0; - - -endmodule diff --git a/source/link_timer.v b/source/link_timer.v deleted file mode 100644 index 7b501ff..0000000 --- a/source/link_timer.v +++ /dev/null @@ -1,67 +0,0 @@ -/* - * link_timer.v - * - * Copyright 2020 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: Generate link timer pulse (1.6 and 10 ms) per SGMII and IEEE 802.3 - * - */ - -module link_timer( - input rstn, - input clk, // 125 MHz data clock - output pulse_1_6ms, - output pulse_10ms -); - - reg [13:0] cnt; // 0.1 ms counter - reg [3:0] cnt_1_6ms; - reg [6:0] cnt_10ms; - - // 0.1 ms counter - always @ (posedge clk or negedge rstn) - if ( !rstn ) - cnt <= 'd0; - else if (cnt == 'd12500) - cnt <= 'd0; - else - cnt <= cnt + 1; - - // 1.6 ms counter - always @ (posedge clk or negedge rstn) - if ( !rstn ) - cnt_1_6ms <= 'd0; - else if (cnt == 'd12500) - if (cnt_1_6ms == 'd16) - cnt_1_6ms <= 'd0; - else - cnt_1_6ms <= cnt_1_6ms + 1; - - assign pulse_1_6ms = (cnt == 'd12500 && cnt_1_6ms == 'd15); - - // 10 ms counter - always @ (posedge clk or negedge rstn) - if ( !rstn ) - cnt_10ms <= 'd0; - else if (cnt == 'd12500) - if (cnt_10ms == 'd99) - cnt_10ms <= 'd0; - else - cnt_10ms <= cnt_10ms + 1; - - assign pulse_10ms = (cnt == 'd12500 && cnt_10ms == 'd99); - - -endmodule \ No newline at end of file diff --git a/source/mac.v b/source/mac.v deleted file mode 100644 index b5b980a..0000000 --- a/source/mac.v +++ /dev/null @@ -1,973 +0,0 @@ -/* - * mac.v - * - * Copyright 2018, 2019, 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: Ethernet MAC Layer - * - */ - -module mac( - input rstn, - input phy_resetn, // The external PHY has its reset signal asserted - input clk, - input tap_port, - - // PCS / SERDES health - input rx_lsm, - input rx_cv_err, - input rx_disp_err, - input rx_cdr_lol, - input rx_los, - - // AN - input [1:0] phy_type, // SGMII==0, SX=1, SMA=3 - input pulse_1_6ms, // SGMII - input pulse_10ms, // SX - input [1:0] fixed_speed, - input an_disable, - output an_duplex, - output phy_up, - output reg mode_100Mbit, - - // Switch I/F - input [2:0] tx_mode, - output reg tx_f, - - // PCS data I/F - input rx_k, - input [7:0] rx_data, - output reg tx_k, - output reg [7:0] tx_data, - output reg tx_disp_correct, - - // TX FCS - output reg fcs_init, - output reg fcs_enable, - output reg [1:0] fcs_addr, - output reg [7:0] fcs_dout, - input [7:0] fcs_din, - - // MAC RX / FIFO Write - output rx_fifo_we, - output [8:0] rx_fifo_d, - output reg rx_error, - output rx_keep, - output reg rx_wr_done, - output reg [10:0] rx_byte_cnt, - output [1:0] rx_mode, - - // MAC TX / FIFO Read - input [10:0] tx_byte_cnt_i, - input [2:0] tx_src_sel, - output reg tx_fifo_re, - input [8:0] tx_fifo_d, - input tx_fifo_empty, - - // Packet Filter - output rx_sample, - output reg ipv4_pkt_start, - output reg trigger, - - output reg rx_k_m1, - output reg rx_k_m2, - output reg rx_k_m3, - output reg rx_k_m4, - - output reg[7:0] rx_data_m1, - output reg[7:0] rx_data_m2, - output reg[7:0] rx_data_m3, - output reg[7:0] rx_data_m4, - - // Param RAM - output [10:0] dpr_ad, - output dpr_we, - output dpr_ce, - input [8:0] dpr_di, - output [8:0] dpr_do, - - // Flags, Metrics, Interrupts, and Debug - output reg rx_enet_bcast, - output reg rx_ipv4_arp, - output reg mac_int, - output reg rx_sop, // start of packet - output reg rx_eop, - output reg tx_sop, - output reg tx_eop, - output reg metrics_start, - input [8:0] metrics_d, - output reg rx_active, - output reg tx_active -); - -`include "sgmii_params.v" -`include "ethernet_params.v" - -localparam PHY_TYPE_SGMII = 2'b00, - PHY_TYPE_SX = 2'b01, - PHY_TYPE_RSVD = 2'b10, - PHY_TYPE_SMA = 2'b11; - -localparam AN_TX_CONFIG_HI = 8'h00, - AN_TX_CONFIG_HI_ACK = 8'h40, - AN_TX_CONFIG_LO = 8'h21; - -localparam RX_ST_IDLE=4'h0, RX_ST_SOP=4'h1, RX_ST_PREAMBLE=4'h2, RX_ST_SFD=4'h3, RX_ST_MAC_ADDR=4'h4, - RX_ST_MAC_TYPE0=4'h5, RX_ST_MAC_TYPE1=4'h6, RX_ST_DATA=4'h7, RX_ST_DATA_DONE0=4'h8, - RX_ST_DATA_DONE1=4'h9, RX_ST_DATA_DONE2=4'ha; - -localparam TX_ST_0=4'h0, TX_ST_1=4'h1, TX_ST_2=4'h2, TX_ST_3=4'h3, - TX_ST_4=4'h4, TX_ST_5=4'h5, TX_ST_6=4'h6, TX_ST_7=4'h7, - TX_ST_8=4'h8, TX_ST_9=4'h9, TX_ST_A=4'ha, TX_ST_B=4'hb, - TX_ST_C=4'hc, TX_ST_D=4'hd, TX_ST_E=4'he, TX_ST_F=4'hf; - -// AN -wire [15:0] tx_config_reg; -wire [1:0] an_speed; - -reg [3:0] rx_cnt_100mbit, tx_cnt_100mbit; -wire tx_sample, tx_sample_re; -wire rx_packet_complete; -wire mode_1Gbit; - -reg [3:0] rx_state; -reg [10:0] rx_pkt_length; -reg [15:0] rx_l3_proto; - -// TODO: consider reorganizing state machines to reuse registers. -reg [7:0] tx_data_an, tx_data_idle, tx_data_pkt; -reg tx_k_an, tx_k_idle, tx_k_pkt; - -// Transmit Registers and Wires -reg [3:0] tx_state; // transmit state machine -reg [10:0] tx_byte_cnt; -reg [10:0] param_addr; - -reg tx_f_an, tx_f_idle, tx_f_pkt; -reg i_tx_disp_correct; -reg tx_last_byte; - -// FIFOs: -reg [8:0] tx_fifo_d_m1; - -// FCS -reg fcs_addr_e; - -// pipeline the param RAM for timing -reg [8:0] dpr_di_reg; - -// counter for detecting Ethernet broadcast, only needs to count to 6 -reg [2:0] rx_enet_bcast_cnt; - -// layer 3 TX support -reg [18:0] tx_ipv4_cksum; -reg [15:0] tx_ipv4_length; - -// layer 4 TX support -reg [15:0] tx_udp_length; - -wire tx_finished; -wire tx_temp; - - -/* - * RX DIRECTION - * - */ - -/* - * A shallow pool of RX registers for analysis - */ -always @(posedge clk or negedge rstn) - begin - if (!rstn) - begin - rx_k_m1 <= 1'b0; - rx_k_m2 <= 1'b0; - rx_k_m3 <= 1'b0; - rx_k_m4 <= 1'b0; - rx_data_m1 <= 8'h0; - rx_data_m2 <= 8'h0; - rx_data_m3 <= 8'h0; - rx_data_m4 <= 8'h0; - end - else if (mode_1Gbit || rx_sample || rx_state == RX_ST_IDLE || rx_state == RX_ST_DATA_DONE2 ) - begin - rx_k_m1 <= rx_k; - rx_k_m2 <= rx_k_m1; - rx_k_m3 <= rx_k_m2; - rx_k_m4 <= rx_k_m3; - rx_data_m1 <= rx_data; - rx_data_m2 <= rx_data_m1; - rx_data_m3 <= rx_data_m2; - rx_data_m4 <= rx_data_m3; - end - end - -// Auto Negotiation -an an_inst ( - .rstn(rstn), - .phy_resetn(phy_resetn), - .clk(clk), - // AN - .phy_type(phy_type), - .pulse_1_6ms(pulse_1_6ms), - .pulse_10ms(pulse_10ms), - .fixed_speed(fixed_speed), - .an_disable(an_disable), - .an_duplex(an_duplex), - .an_speed(an_speed), - .an_link_up(an_link_up), - .tx_config_reg(tx_config_reg), - .phy_up(phy_up), - - .rx_k_m1(rx_k_m1), - .rx_k_m2(rx_k_m2), - .rx_k_m3(rx_k_m3), - .rx_k_m4(rx_k_m4), - - .rx_data_m1(rx_data_m1), - .rx_data_m2(rx_data_m2), - .rx_data_m3(rx_data_m3), - .rx_data_m4(rx_data_m4) - ); - - -// 100 MBit Support. There are no plans to support 10 MBit, so 100 MBit inactive is the same as 1GBit active -// if/else encodes the priority -always @(*) - if (fixed_speed == SGMII_SPEED_100MBIT) - mode_100Mbit = 1'b1; - else if (fixed_speed == SGMII_SPEED_1GBIT) - mode_100Mbit = 1'b0; - else if (an_speed == SGMII_SPEED_100MBIT ) - mode_100Mbit = 1'b1; - else - mode_100Mbit = 1'b0; - -assign mode_1Gbit = ~mode_100Mbit; - -// RX 100 Mbit support -assign rx_sample = (rx_cnt_100mbit == 4'd9 && mode_100Mbit) || !mode_100Mbit ? 1'b1 : 1'b0; -always @(posedge clk or negedge rstn) - if (!rstn) - rx_cnt_100mbit <= 4'b0; - else if ( rx_cnt_100mbit == 4'd9 || rx_sop ) - rx_cnt_100mbit <= 4'b0; - else - rx_cnt_100mbit <= rx_cnt_100mbit + 4'd1; - - -/* - * rx_state machine - * capture the Ethernet MAC header + packet. - * - */ -always @(posedge clk, negedge rstn) - if (!rstn) - rx_state <= RX_ST_IDLE; - else if ( rx_eop || !phy_resetn ) // EOP will reset state machine - rx_state <= RX_ST_IDLE; - else if ( phy_up ) - case ( rx_state ) - RX_ST_IDLE: if (rx_data_m1 == K27_7 && rx_k_m1 ) // Found /S/ - rx_state <= RX_ST_SOP; - RX_ST_SOP: if ( rx_sample ) // Capture /S/ - rx_state <= RX_ST_PREAMBLE; - RX_ST_PREAMBLE: if ( rx_sample && rx_data_m1 == 8'hd5 ) // 0xd5 preamble - rx_state <= RX_ST_SFD; - RX_ST_SFD: if ( rx_sample ) - rx_state <= RX_ST_MAC_ADDR; - RX_ST_MAC_ADDR: if ( rx_sample && rx_byte_cnt == 12 ) // Use this state transition to signal end of ethernet header and start of packet - rx_state <= RX_ST_MAC_TYPE0; - RX_ST_MAC_TYPE0: if ( rx_sample ) - rx_state <= RX_ST_MAC_TYPE1; // Capture ethertype - RX_ST_MAC_TYPE1: if ( rx_sample ) - rx_state <= RX_ST_DATA; // - RX_ST_DATA: if ( rx_sample && rx_packet_complete ) // write into FIFO until pkt length - rx_state <= RX_ST_DATA_DONE0; - RX_ST_DATA_DONE0: if ( rx_sample ) - rx_state <= RX_ST_DATA_DONE1; // write an extra byte into the FIFO - RX_ST_DATA_DONE1: if ( rx_sample ) - rx_state <= RX_ST_DATA_DONE2; // write an extra byte into the FIFO - RX_ST_DATA_DONE2: if ( rx_sample ) - rx_state <= rx_state; // waiting for /T/ - default: rx_state <= rx_state; - endcase - else - rx_state <= RX_ST_IDLE; - -/* - * rx_fifo_we -*/ -assign rx_fifo_we = ( rx_sample && ( rx_state >= RX_ST_SFD && rx_state <= RX_ST_DATA_DONE1 ) ) ? 1'b1 : 1'b0; - -// rx_mode -assign rx_mode = 2'b00; - - -/* - * Detect Ethernet Broadcast (destination address = ff:ff:ff:ff:ff:ff) - * TODO: Add state information to only trigger on DEST ADDRESS - * - */ -always @(posedge clk, negedge rstn) - if (!rstn) - rx_enet_bcast_cnt <= 3'h0; - else if ( rx_sample ) - if (rx_data_m1 == 9'hff) - rx_enet_bcast_cnt <= rx_enet_bcast_cnt + 1; - else - rx_enet_bcast_cnt <= 3'h0; - -/* Ethernet Broadcast Dest Address, must be a one shot */ -always @(posedge clk, negedge rstn) - if (!rstn) - rx_enet_bcast <= 1'b0; - else if ( rx_sample ) - if ( rx_enet_bcast_cnt == 3'h6 ) - rx_enet_bcast <= 1'b1; - else - rx_enet_bcast <= 1'b0; - -/* - create a one shot that will assert during RX_ST_DATA_DONE1 so external logic can know - that the FIFO write has come to an end ( reset pointers, etc. ) - - For 100Mbit, since the states change 10 clocks apart, set it during RX_ST_DATA_DONE1 -*/ -always @(posedge clk, negedge rstn) - if (!rstn) - rx_wr_done <= 1'b0; - else if ( mode_1Gbit && rx_state == RX_ST_DATA_DONE0 ) - rx_wr_done <= 1'b1; - else if ( mode_100Mbit && rx_sample && rx_state == RX_ST_DATA_DONE1 ) - rx_wr_done <= 1'b1; - else - rx_wr_done <= 1'b0; - -/* capture layer 3 protocol (e.g., ipv4 or ipv6) */ -always @(posedge clk, negedge rstn) - if ( !rstn ) - rx_l3_proto <= 0; - else if ( rx_sop ) - rx_l3_proto <= 0; - else if ( rx_sample && rx_state == RX_ST_MAC_TYPE0 ) - rx_l3_proto <= { rx_data_m2, rx_data_m1 }; - -// assert ipv4 ARP flag for filtering operations -always @(posedge clk, negedge rstn) - if (!rstn) - rx_ipv4_arp <= 1'b0; - else if ( rx_sample && rx_state == RX_ST_MAC_TYPE1 && rx_l3_proto == ETHER_TYPE_ARP) - rx_ipv4_arp <= 1'b1; - else - rx_ipv4_arp <= 1'b0; - -/* - * rx_keep flag - * signals must be one shot - * - */ - assign rx_keep = rx_enet_bcast | rx_ipv4_arp; - -/* rx_error - * TODO: should be one shot? - * */ -always @(*) - if ( rx_sample && rx_state >= RX_ST_DATA && ( rx_l3_proto != ETHER_TYPE_IPV4 && rx_l3_proto != ETHER_TYPE_IPV6 && rx_l3_proto != ETHER_TYPE_ARP) ) - rx_error = 1; - else - rx_error = 0; - -/* rx_byte_cnt */ -always @(posedge clk, negedge rstn) - if (!rstn) - rx_byte_cnt <= 'h0; - else if (rx_sample) - if ( rx_state == RX_ST_IDLE || rx_state == RX_ST_PREAMBLE ) - rx_byte_cnt <= 'h0; - else if ( rx_state == RX_ST_MAC_TYPE0 ) - rx_byte_cnt <= 'h1; - else - rx_byte_cnt <= rx_byte_cnt + 1; - -/* rx_pkt_length */ -always @(posedge clk, negedge rstn) - if ( !rstn ) - rx_pkt_length <= 0; - else if ( rx_sop ) - rx_pkt_length <= 0; - else if (rx_sample) - if ( rx_l3_proto == ETHER_TYPE_IPV4 && rx_state == RX_ST_DATA && rx_byte_cnt == 'h4 ) - rx_pkt_length <= { rx_data_m2[2:0], rx_data_m1 }; - else if ( rx_l3_proto == ETHER_TYPE_IPV6 && rx_state == RX_ST_DATA && rx_byte_cnt == 'h6 ) - rx_pkt_length <= { rx_data_m2[2:0], rx_data_m1 } + 'd40; - else if ( rx_l3_proto == ETHER_TYPE_ARP && rx_state == RX_ST_DATA ) - rx_pkt_length <= 'd46; - -/* ipv4 flag */ -always @(posedge clk, negedge rstn) - if ( !rstn ) - ipv4_pkt_start <= 1'b0; - else if ( rx_sample && rx_l3_proto == ETHER_TYPE_IPV4 && rx_state == RX_ST_MAC_TYPE1 ) - ipv4_pkt_start <= 1; - else - ipv4_pkt_start <= 0; - -assign rx_packet_complete = ( rx_sample && rx_state >= RX_ST_DATA && rx_pkt_length == rx_byte_cnt ) ? 1 : 0; - -// FIFO data interface -assign rx_fifo_d[7:0] = rx_data_m1; -assign rx_fifo_d[8] = rx_packet_complete; - - -/* - * rx_sop, K27_7, 0xFB /S/ Start_of_Packet - */ -always @(posedge clk or negedge rstn) - if (!rstn) - rx_sop <=1'b0; - else if ( rx_data_m1 == K27_7 && rx_k_m1 == 1'b1 ) - rx_sop <= 1'b1; - else - rx_sop <= 1'b0; - -/* - * rx_eop, K29_7, 0xFD, /T/ End_of_Packet - */ -always @(posedge clk or negedge rstn) - if (!rstn) - rx_eop <=1'b0; - else if ( rx_data_m1 == K29_7 && rx_k_m1 == 1'b1 ) - rx_eop <= 1'b1; - else - rx_eop <= 1'b0; - -/* MAC Interrupt - * Create one shot interrupt while interrupt source is active - * Rely on interrupt controller to latch & clear - */ -always @(posedge clk or negedge rstn) - if (!rstn) - mac_int <=1'b0; - else if ( !rx_lsm || rx_cv_err || rx_cdr_lol || rx_los ) - mac_int <= 1'b1; - else - mac_int <= 1'b0; - - -/* Debug RX */ -always @(posedge clk or negedge rstn) - if (!rstn) - rx_active <=1'b0; - else if ( rx_state != 0 ) - rx_active <= 1'b1; - else - rx_active <= 1'b0; - - - -/* - * TX DIRECTION - * - */ - - -// TX 100 Mbit support -assign tx_sample_re = (tx_cnt_100mbit == 4'd8 && mode_100Mbit) || !mode_100Mbit; -assign tx_sample = (tx_cnt_100mbit == 4'd9 && mode_100Mbit) || !mode_100Mbit; - -always @(posedge clk or negedge rstn) - if (!rstn) - tx_cnt_100mbit <= 4'b0; - else if ( tx_state == TX_ST_0 ) - tx_cnt_100mbit <= 4'b1; // steal a bit here during preamble so we keep an even bit count - else if ( tx_cnt_100mbit == 4'd9 ) - tx_cnt_100mbit <= 4'b0; - else - tx_cnt_100mbit <= tx_cnt_100mbit + 1; - - -/* -* -* Transmit Mux -*/ -always @(posedge clk or negedge rstn) - if (!rstn) begin - tx_data <= 8'h00; - tx_k <= 1'b0; - tx_disp_correct <= 1'b0; - end - else begin - case(tx_mode) - TX_MODE_AN: - begin - tx_data <= tx_data_an; - tx_k <= tx_k_an; - tx_disp_correct <= i_tx_disp_correct; - end - TX_MODE_IDLE: - begin - tx_data <= tx_data_idle; - tx_k <= tx_k_idle; - tx_disp_correct <= i_tx_disp_correct; - end - default: - begin - tx_data <= tx_data_pkt; - tx_k <= tx_k_pkt; - tx_disp_correct <= i_tx_disp_correct; - end - endcase - end - -// tx_f mux -always @(*) - case(tx_mode) - TX_MODE_AN: tx_f <= tx_f_an; - TX_MODE_IDLE: tx_f <= tx_f_idle; - default : tx_f <= tx_f_pkt; - endcase - - -/* - * CONFIG SM -* During SGMII auto negotiation, send /C1/ and /C2/ ordered sets -* C1: /K28.5/D21.5/Config Regs -* C2: /K28.5/D2.2/Config Regs -*/ -always @(*) - begin - tx_f_an = 1'b0; - tx_k_an = 1'b0; - case(tx_byte_cnt[2:0]) - 3'd0: - begin - tx_data_an = K28_5; - tx_k_an = 1'b1; - end - 3'd1: - tx_data_an = D21_5; - 3'd2: - tx_data_an = AN_TX_CONFIG_LO; - 3'd3: - if (!an_link_up) - tx_data_an = AN_TX_CONFIG_HI; - else - tx_data_an = AN_TX_CONFIG_HI_ACK; - 3'd4: - begin - tx_data_an = K28_5; - tx_k_an = 1'b1; - end - 3'd5: - tx_data_an = D2_2; - 3'd6: - tx_data_an = AN_TX_CONFIG_LO; - 3'd7: - if (!an_link_up) - begin - tx_f_an = 1'b1; - tx_data_an = AN_TX_CONFIG_HI; - end - else - begin - tx_f_an = 1'b1; - tx_data_an = AN_TX_CONFIG_HI_ACK; - end - default: - begin - tx_data_an = K_ERROR; - tx_k_an = 1'b1; - tx_f_an = 1'b1; - end - endcase - end - -/* IDLE2 SM */ -always @(*) - begin - tx_f_idle = 1'b0; - case(tx_byte_cnt[1:0]) - 3'd0: - begin - tx_data_idle = K28_5; - tx_k_idle = 1'b1; - end - 3'd1: - begin - tx_data_idle = D16_2; - tx_k_idle = 1'b0; - tx_f_idle = 1'b1; - end - default: - begin - tx_data_idle = K_ERROR; - tx_k_idle = 1'b1; - tx_f_idle = 1'b1; - end - endcase - end - - -/* - * TX Finished Logic - */ -assign tx_temp = (tx_mode==TX_MODE_XMT_CUSTOM && tx_byte_cnt==tx_ipv4_length+SZ_ETH_HEADER); -assign tx_finished = tx_last_byte || (tx_mode==TX_MODE_XMT_CUSTOM && tx_byte_cnt==(tx_ipv4_length+SZ_ETH_HEADER)); - - - - -/* -* Transmit Packet State Machine -* -* -* Note: the first /I/ following a transmitted frame or Configuration ordered set -* restores the current positive or negative running disparity to a -* negative value. -* -*/ -always @(posedge clk, negedge rstn) - begin - if ( !rstn ) - tx_state <= TX_ST_0; - else if ( !phy_resetn ) - tx_state <= TX_ST_0; - else - case(tx_state) - TX_ST_0: if ( tx_mode >= TX_MODE_XMT_PKT && !tx_f_pkt ) // /S/ - tx_state <= TX_ST_1; - TX_ST_1: if ( tx_sample && tx_byte_cnt == 8'h5 ) // preamble 0x55 - tx_state <= TX_ST_2; - TX_ST_2: if ( tx_sample ) - tx_state <= TX_ST_3; // preamble 0x55, assert tx_fifo_re, reset tx_byte_cnt - TX_ST_3: if ( tx_sample ) - tx_state <= TX_ST_4; // preamble 0xD5 - TX_ST_4: if ( tx_sample && tx_finished && tx_byte_cnt < 60 ) // check if we need to pad? - tx_state <= TX_ST_5; - else if ( tx_sample && tx_finished) // check if we're done - tx_state <= TX_ST_6; - TX_ST_5: if ( tx_sample && tx_byte_cnt >= 60 ) // pad state, test for sufficient frame size - tx_state <= TX_ST_6; - TX_ST_6: if ( tx_sample && fcs_addr == 2'b10 ) // Start FCS - tx_state <= TX_ST_7; - TX_ST_7: if (tx_sample && fcs_addr == 2'b11 ) // Finish FCS - tx_state <= TX_ST_8; - TX_ST_8: tx_state <= TX_ST_9; // EOP /T/ - TX_ST_9: if ( tx_byte_cnt[0] && !mode_100Mbit) // test for odd # of code words when in Gig mode for extra /R/ insertion - tx_state <= TX_ST_A; - else - tx_state <= TX_ST_B; - TX_ST_A: tx_state <= TX_ST_B; // 2nd /R/ if necessary ( odd position ) - TX_ST_B: tx_state <= TX_ST_C; // I2, K28.5 - TX_ST_C: tx_state <= TX_ST_0; // I2, D16.2 - - default: tx_state <= tx_state; - endcase - end - -/* -* tx related data mux and control signals -* TODO: add additional states for stuffing header values -* TODO: this will need to be registered at some point -* -*/ -always @(*) - begin - tx_f_pkt = 1'b0; - tx_k_pkt = 1'b0; - i_tx_disp_correct = 1'b0; - tx_last_byte = 1'b0; - fcs_init = 1'b0; - fcs_addr_e = 1'b0; - fcs_dout = tx_fifo_d_m1[7:0]; - metrics_start = 1'b0; - case(tx_state) - TX_ST_0: - begin - tx_data_pkt = K27_7; // start of packet - tx_k_pkt = 1'b1; - fcs_init = 1'b1; - end - TX_ST_1: begin - tx_data_pkt = 8'h55; // preamble, we need 6 bytes total of 0x55 - end - TX_ST_2: begin - tx_data_pkt = 8'h55; // preamble, single byte of 0x55 and assert fifo_re - end - TX_ST_3: begin - tx_data_pkt = 8'hD5; // preamble, single byte of 0xd5 completes the preamble) - end - TX_ST_4: - begin - if (tx_mode == TX_MODE_XMT_CUSTOM && tx_byte_cnt == 'd17) begin - tx_data_pkt = tx_ipv4_length[15:8]; - fcs_dout = tx_ipv4_length[15:8]; - end - else if (tx_mode == TX_MODE_XMT_CUSTOM && tx_byte_cnt == 'd18) begin - tx_data_pkt = tx_ipv4_length[7:0]; - fcs_dout = tx_ipv4_length[7:0]; - end - else if (tx_mode == TX_MODE_XMT_CUSTOM && tx_byte_cnt == 'd25) begin - tx_data_pkt = tx_ipv4_cksum[15:8]; - fcs_dout = tx_ipv4_cksum[15:8]; - end - else if (tx_mode == TX_MODE_XMT_CUSTOM && tx_byte_cnt == 'd26) begin - tx_data_pkt = tx_ipv4_cksum[7:0]; - fcs_dout = tx_ipv4_cksum[7:0]; - end - else if (tx_mode == TX_MODE_XMT_CUSTOM && tx_byte_cnt == 'd38) begin - tx_data_pkt = 8'h0 + tx_src_sel[2]; // UDP destination port - fcs_dout = 8'h0 + tx_src_sel[2]; - end - else if (tx_mode == TX_MODE_XMT_CUSTOM && tx_byte_cnt == 'd39) begin - tx_data_pkt = tx_udp_length[15:8]; - fcs_dout = tx_udp_length[15:8]; - end - else if (tx_mode == TX_MODE_XMT_CUSTOM && tx_byte_cnt == 'd40) begin - tx_data_pkt = tx_udp_length[7:0]; - fcs_dout = tx_udp_length[7:0]; - end - else if ( (tx_mode == TX_MODE_XMT_METRICS || tx_mode == TX_MODE_XMT_CUSTOM) - && tx_byte_cnt <= SZ_ETH_HEADER + SZ_IPV4_HEADER + SZ_UDP_HEADER ) - begin - tx_data_pkt = dpr_di_reg[7:0]; // packet headers - fcs_dout = dpr_di_reg[7:0]; - metrics_start = 1'b1; // keeps the metrics counters in reset - end - else if ( tx_mode == TX_MODE_XMT_METRICS ) - begin - tx_data_pkt = metrics_d; // packet content - fcs_dout = metrics_d[7:0]; - tx_last_byte = metrics_d[8]; - end - else - begin - tx_data_pkt = tx_fifo_d_m1[7:0]; // read data from FIFO - tx_last_byte = tx_fifo_d_m1[8]; - end - end - TX_ST_5: - begin - tx_data_pkt = 8'h00; // pad - fcs_dout = 8'h00; - end - TX_ST_6: begin - tx_data_pkt = fcs_din; // read from fcs - fcs_addr_e = 1'b1; - end - TX_ST_7: begin - tx_data_pkt = fcs_din; // read from fcs - fcs_addr_e = 1'b1; - end - TX_ST_8: - begin - tx_data_pkt = K29_7; // end of packet - tx_k_pkt = 1'b1; - end - TX_ST_9: - begin - tx_data_pkt = K23_7; // carrier extend - tx_k_pkt = 1'b1; - end - TX_ST_A: - begin - tx_data_pkt = K23_7; // carrier extend - tx_k_pkt = 1'b1; - end - TX_ST_B: - begin - tx_data_pkt = K28_5; // 1st idle code - tx_k_pkt = 1'b1; - end - TX_ST_C: - begin - tx_data_pkt = D16_2; // 2nd idle code - i_tx_disp_correct = 1'b1; // PCS may convert D16.2 to a D5.6 for I2 to flip disparity - tx_f_pkt = 1'b1; - end - default: - begin - tx_data_pkt = K_ERROR; - tx_k_pkt = 1'b1; - tx_f_pkt = 1'b1; - end - endcase -end - -/* - * tx_fifo_re - * - * The use of the read fifo is different between 1Gbit and 100Mbit. - * - */ -always @(*) - if ( tx_mode == TX_MODE_XMT_PKT ) - if ( mode_1Gbit && tx_state >= TX_ST_2 && tx_state <= TX_ST_4 ) - tx_fifo_re = 1'b1; - else if ( mode_100Mbit && tx_sample_re && tx_state > TX_ST_2 && tx_state <= TX_ST_4 ) - tx_fifo_re = 1'b1; - else if ( mode_100Mbit && tx_state == TX_ST_8 ) // we need an extra FIFO strobe at 100MBit for a single 1G clk - tx_fifo_re = 1'b1; - else - tx_fifo_re = 1'b0; - else if (tx_mode == TX_MODE_XMT_CUSTOM && tx_state == TX_ST_4 && tx_byte_cnt > SZ_ETH_HEADER + SZ_IPV4_HEADER + SZ_UDP_HEADER - 2) - tx_fifo_re = 1'b1; - else - tx_fifo_re = 1'b0; - - -always @(posedge clk, negedge rstn) - if (!rstn) - param_addr <= 'h0; - else if (tx_sample) - if ( mode_100Mbit && tx_state == TX_ST_1 && tx_byte_cnt == 'h5 ) - param_addr <= 'h0; - else if ( mode_1Gbit && tx_state == TX_ST_1 && tx_byte_cnt == 'h2 ) - param_addr <= 'h0; - else - param_addr <= param_addr + 1; - -/* - tx_byte_cnt - - Increment at pcs clock rate for PCS layer data (e.g., /I1/, /C/, /S/, etc. - - Increment at sample rate for Ethernet data - -*/ -always @(posedge clk, negedge rstn) - if (!rstn) - tx_byte_cnt <= 'h0; - else if (tx_sample || tx_state == TX_ST_0 || tx_state > TX_ST_7 || tx_mode < TX_MODE_XMT_PKT ) - if (tx_f) - tx_byte_cnt <= 'h0; - else if ( tx_state == TX_ST_2 ) - tx_byte_cnt <= 'h0; // start counting the Ethernet Frame after preamble - else - tx_byte_cnt <= tx_byte_cnt + 1; - -/* - * pipeline data from FIFO - */ -always @(posedge clk or negedge rstn) -begin - if ( !rstn ) - tx_fifo_d_m1 <= 9'h0; - else if ( tx_sample ) - tx_fifo_d_m1 <= tx_fifo_d; -end - -/* -* FCS -*/ -always @(posedge clk or negedge rstn) - begin - if ( !rstn ) - fcs_addr <= 2'b00; - else if (tx_sample) - if ( !fcs_addr_e ) - fcs_addr <= 2'b00; - else - fcs_addr <= fcs_addr + 1; - end - -always @(*) - if (mode_1Gbit && (tx_state == TX_ST_4 || tx_state == TX_ST_5) ) - fcs_enable = 1'b1; - else if ( mode_100Mbit && tx_sample && (tx_state == TX_ST_4 || tx_state == TX_ST_5) ) - fcs_enable = 1'b1; - else - fcs_enable = 1'b0; - -/* -* DPRAM, param ram Control for TAP port -*/ -always @(posedge clk or negedge rstn) - if ( !rstn ) - dpr_di_reg <= 9'h0; - else if (tx_sample) - dpr_di_reg <= dpr_di; - - -assign dpr_we = 1'b0; -assign dpr_ce = 1'b1; -assign dpr_ad = param_addr; -assign dpr_do = 9'd0; - -/* - * tx_sop, K27_7, 0xFB /S/ Start_of_Packet - * We choose to not include TX_MODE_CUSTOM_PKT for this metric - */ -always @(posedge clk or negedge rstn) - if (!rstn) - tx_sop <=1'b0; - else if ( tx_state == TX_ST_0 && tx_mode >= TX_MODE_XMT_PKT ) - tx_sop <= 1'b1; - else - tx_sop <= 1'b0; - - /* - * tx_eop, K29_7, 0xFD, /T/ End_of_Packet - */ -always @(posedge clk or negedge rstn) - if (!rstn) - tx_eop <=1'b0; - else if ( tx_state == TX_ST_7 ) - tx_eop <= 1'b1; - else - tx_eop <= 1'b0; - -// Layer 3 TX Support -always @(posedge clk or negedge rstn) - if (!rstn) - tx_ipv4_length <= 16'h0000; - else if ( tx_state == TX_ST_1 ) - tx_ipv4_length <= {5'h00, tx_byte_cnt_i} +SZ_IPV4_HEADER + SZ_UDP_HEADER; - -// tx_ipv4_cksum -always @(posedge clk or negedge rstn) - if (!rstn) - tx_ipv4_cksum <= 18'h00000; - else if ( tx_state == TX_ST_2 ) - tx_ipv4_cksum <= {10'h000, dpr_di_reg[7:0]}; - else if ( tx_state == TX_ST_3 ) - tx_ipv4_cksum <= {2'b00, dpr_di_reg[7:0], tx_ipv4_cksum[7:0]}; - else if (tx_state == TX_ST_4 && tx_byte_cnt == 'd1) - tx_ipv4_cksum <= tx_ipv4_cksum + tx_ipv4_length; - else if (tx_state == TX_ST_4 && tx_byte_cnt == 'd2) - tx_ipv4_cksum <= {2'b00,tx_ipv4_cksum[15:0]} + {16'h0000,tx_ipv4_cksum[17:16]}; - else if (tx_state == TX_ST_4 && tx_byte_cnt == 'd3) - tx_ipv4_cksum <= {2'b00, ~tx_ipv4_cksum[15:0]}; - -// Layer 4 TX Support -always @(posedge clk or negedge rstn) - if (!rstn) - tx_udp_length <= 16'h0000; - else if ( tx_state == TX_ST_1 ) - tx_udp_length <= {5'h00, tx_byte_cnt_i} + SZ_UDP_HEADER; - -/* Debug TX */ -always @(posedge clk or negedge rstn) - if (!rstn) - tx_active <=1'b0; - else if ( tx_state == TX_ST_1 ) - tx_active <= 1'b1; - else - tx_active <= 1'b0; - -endmodule diff --git a/source/mdio.v b/source/mdio.v deleted file mode 100644 index 3339dcc..0000000 --- a/source/mdio.v +++ /dev/null @@ -1,146 +0,0 @@ -/* - * mdio.v - * - * Copyright (C) 2018, 2019 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: MDIO HW driver / bit banger - * - */ - - -`timescale 1ns /10ps - -module mdio( - input rstn, - input mdc, // clock - - // mdio - input mdi, - output reg mdo, - output reg mdo_oe, - - // mdio_controller interface - input rwn, // read / write not - input [4:0] phy_addr, - input [4:0] reg_addr, - input [15:0] di, - input ld, // load, start - output reg run, - output done, // mdio xfer is done - - // output port to converter - output reg [15:0] dout, - output we -); - - reg [5:0] state; - reg [15:0] d; - - // run state machine - // run starts when ld is asserted and finishes when done is asserted - always @(negedge mdc or negedge rstn) - begin - if ( !rstn) - run <= 1'b0; - else if ( ld ) - run <= 1'b1; - else if ( done ) - run <= 1'b0; - end - - - // increment state during run - always @(negedge mdc or negedge rstn) - begin - if ( !rstn ) - state <= 0; - else if ( ld ) - state <= 0; - else if ( run ) - state <= state + 1; - end - - // register data for MDIO TX - always @(negedge mdc or negedge rstn) - begin - if ( !rstn ) - d <= 0; - else if ( ld ) - d <= di; - end - - // done combo logic - assign done = ( state == 6'd36 ) ? 1'b1 : 1'b0; - - // only assert we on mdio reads - assign we = done && rwn; - - // mdo_oe logic - always @(*) - begin - mdo_oe = 1'b0; - if ( run && !rwn && state < 6'd36 ) - mdo_oe = 1'b1; - else if ( run && rwn && state < 6'd14 ) - mdo_oe = 1'b1; - end - - // mdo mux - always @(*) - begin - mdo = 1'b0; - casez(state) - 6'h0: mdo = 1'b0; - 6'h1: mdo = 1'b1; - 6'h2: if (rwn) - mdo = 1'b1; - else - mdo = 1'b0; - 6'h3: if (rwn) - mdo = 1'b0; - else - mdo = 1'b1; - 6'h4: mdo = phy_addr[4]; - 6'h5: mdo = phy_addr[3]; - 6'h6: mdo = phy_addr[2]; - 6'h7: mdo = phy_addr[1]; - 6'h8: mdo = phy_addr[0]; - 6'h9: mdo = reg_addr[4]; - 6'ha: mdo = reg_addr[3]; - 6'hb: mdo = reg_addr[2]; - 6'hc: mdo = reg_addr[1]; - 6'hd: mdo = reg_addr[0]; - 6'he: mdo = 1'b1; // it's a don't care if we're doing a read - 6'hf: mdo = 1'b0; - 6'h1?: mdo = rwn ? 1'b1 : d[31-state]; // msbit - default: mdo = 1'b1; - endcase - end - - - /* - * capture mdi on rising edge - * data out shift register - * ( shift into it from mdio to parallel reg ) - */ - always @(posedge mdc or negedge rstn) - begin - if ( !rstn ) - dout <= 16'h0; - else if ( rwn && run && ( state >= 16 && state <= 31 )) - dout <= { dout[14:0], mdi }; - end - -endmodule diff --git a/source/mdio_cont.v b/source/mdio_cont.v deleted file mode 100644 index ad595fd..0000000 --- a/source/mdio_cont.v +++ /dev/null @@ -1,159 +0,0 @@ -/* - * mdio_cont.v - * - * Copyright (C) 2018, 2019 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: MDIO controller / state machine - * - */ - -`timescale 1ns /10ps - -module mdio_controller #(parameter ADDR_SZ = 6) -( - - // system interface - input rstn, - input clk, // mdio mdc clock - - // worker interface - input work_start, - output reg work_run, - output reg work_done, - input [ADDR_SZ-1:0] routine_addr, - - // arbitration - input buffer_full, - - // memory interface - output reg [ADDR_SZ-1:0] addr, // controller address - input [7:0] di, // controller data bus - - // mdio interface - output reg [4:0] reg_addr, - output reg [15:0] dout, // data output ( for writes ) - output ld, // load control / address, - output reg rwn, // read / write not - input done -); - - localparam ST_SZ = 4; - reg [ST_SZ-1:0] cont_state; - wire ld_dl, ld_dh; - - - // state encoding - 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; - - - /* - * keep running until an eop is found - */ - always @(posedge clk or negedge rstn) - begin - if (!rstn) - cont_state <= S0; - else - case (cont_state) - S0: if (work_start == 1'b1) cont_state <= S1; - S1: cont_state <= S2; - S2: if ( work_done == 1'b1 ) cont_state <= S0; - else if ( buffer_full ) cont_state <= S2; // wait for the fifo to empty out - else if ( ~rwn ) cont_state <= S3; - else cont_state <= S6; - S3: cont_state <= S4; - S4: cont_state <= S5; - S5: cont_state <= S6; - S6: cont_state <= S7; - S7: if ( done == 1'b1 ) cont_state <= S8; - S8: cont_state <= S1; - endcase - end - - /* read the eop bit during S1 */ - always @(posedge clk or negedge rstn) - begin - if ( !rstn ) - work_done <= 1'b0; - else if ( cont_state == S1 && di[7] == 1'b1 ) - work_done <= 1'b1; - else - work_done <= 1'b0; - end - - /* work_run */ - always @(posedge clk or negedge rstn) - begin - if ( !rstn ) - work_run <= 1'b0; - else if ( work_start == 1'b1 ) - work_run <= 1'b1; - else if ( work_done == 1'b1 ) - work_run <= 1'b0; - end - - /* set RWN for duration of cyle */ - always @(posedge clk or negedge rstn) - begin - if ( rstn == 1'b0 || work_done ==1'b1 ) - begin - rwn <= 1'b1; - end - else if ( cont_state == S1 ) - begin - rwn <= di[5]; - end - end - - /* reg_addr is the mdio register address */ - always @(posedge clk or negedge rstn) - begin - if ( rstn == 1'b0 || work_done ==1'b1 ) - reg_addr <= 5'h0; - else if ( cont_state == S1 ) - reg_addr <= di[4:0]; - end - - /* addr is the program address */ - always @(posedge clk or negedge rstn) - begin - if (rstn == 1'b0 || work_done == 1'b1 ) - addr <= 0; - else if ( work_start == 1'b1 ) - addr <= routine_addr[ADDR_SZ-1:0]; - else if ( cont_state == S3 || cont_state == S4 || cont_state == S8 ) - addr <= addr + 1; - end - - // latch the write data to mdio - always @(posedge clk or negedge rstn) - begin - if (rstn == 0) - dout <= 16'h0000; - else if ( ld_dl == 1'b1 ) - dout[7:0] <= di; - else if ( ld_dh == 1'b1 ) - dout[15:8] <= di; - end - - // combinatorial logic here - assign ld_dl = ( cont_state == S4 ) ? 1'b1 : 1'b0; - assign ld_dh = ( cont_state == S5 ) ? 1'b1 : 1'b0; - assign ld = ( cont_state == S6 ) ? 1'b1 : 1'b0; - - -endmodule diff --git a/source/mdio_data_ti.v b/source/mdio_data_ti.v deleted file mode 100644 index aef537d..0000000 --- a/source/mdio_data_ti.v +++ /dev/null @@ -1,128 +0,0 @@ -/* - * mdio_data_ti.v ( TI DP83867 PHY ) - * - * Copyright (C) 2018, 2019 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: MDIO ROM for TI DP83867 PHY - * - */ - - - -`timescale 1ns /10ps - -module mdio_data_ti #(parameter ADDR_SZ = 7) -( - // params that alter the data returned - input [4:0] page, - input [4:0] reg_addr, - input [7:0] data_in_h, - input [7:0] data_in_l, - - // ROM interface - input oe, - input [ADDR_SZ-1:0]ad, - output [7:0]d -); - -localparam R = 8'h20; -localparam W = 8'h00; -localparam EOP = 8'h80; - -localparam REGCR = 5'h0d; -localparam ADDAR = 5'h0e; - -reg [7:0]data; - -assign d = oe ? data : 8'hzz; - -// register 22 is page -always @ (*) -begin - case (ad) - /* - Subroutine: SGMII Init ( i ) Not Needed for TI PHY, but read PHY Control Register (PHYCR), Address 0x0010 - */ - - // read the PHYCR register, SGMII Enable is bill 11 - 0: data = R|8'h10; // pg 18, reg 20 - - /* - Subroutine: Read Live Status ( s ) - */ - // read the live copper status PHYSTS (0x17) - 20 : data = R|8'h11; // read addr[17] - - /* - Subroutine: Dump Registers 0:3 - */ - 25: data = R|8'd0; - 26 : data = R|8'd1; - 27 : data = R|8'd2; - 28 : data = R|8'd3; - - /* - Subroutine: : Loopback ( 0_0.14 ) - */ - 40 : data = W|8'd0; // write addr[0] - 44 : data = 8'b01000000; // collision, speed select, reserved - 45 : data = 8'b01010001; // reset, loopback, speed, AN enable, power down, isolate, restart AN, duplex; - - // read it back - 46: data = R|8'd0; - - /* - Subroutine: : Read a register. - */ - 48: data = { 3'b001, reg_addr }; - - /* - Subroutine: : Write a register. - */ - 50: data = { 3'b000, reg_addr }; - 51: data = data_in_l; - 52: data = data_in_h; - // read it back - // 53: data = { 3'b001, reg_addr }; - - // y: extended read - 60: data = {3'b000 , REGCR }; - 61: data = 8'h1f; - 62: data = 8'h00; - // Write the extended address to 0xe - 63: data = { 3'b000, ADDAR }; - 64: data = data_in_l; - 65: data = data_in_h; - // Write 0x401f to 0xd - 66: data = { 3'b000, REGCR }; - 67: data = 8'h1f; - 68: data = 8'h40; - // Read value in extended register: read 0x0E - 69: data = { 3'b001, ADDAR }; - - // z: extended write - // Write value in extended register: 0x0E - 80: data = { 3'b000, ADDAR }; - 81: data = data_in_l; - 82: data = data_in_h; - // read it back - 83: data = { 3'b001, ADDAR }; - - default: data = R|EOP; - endcase -end - -endmodule - diff --git a/source/metrics.v b/source/metrics.v deleted file mode 100644 index bce3389..0000000 --- a/source/metrics.v +++ /dev/null @@ -1,102 +0,0 @@ -/* - * metrics.v - * - * Copyright (C) 2018, 2019 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: Collect metrics here and register them for transmit - * - * - */ - -`timescale 1ns /10ps - -module metrics( - input rstn, - input clk, - input mode_100Mbit, - - // input data for gathering metrics - input [3:0] rx_mac_keep, - input rx_pf_keep_01, - input rx_pf_keep_02, - input rx_pf_keep_10, - input rx_pf_keep_12, - input rx_pf_keep_20, - input rx_pf_keep_21, - input rx_pf_keep_23, - - input [3:0] rx_eop, - input [3:0] rx_sop, - input [3:0] tx_eop, - input [3:0] tx_sop, - - // metric outputs - input metrics_start, - output reg [8:0] metrics_d -); - -reg [7:0] rx_pkt_cnt; -reg [7:0] tx_pkt_cnt; - -reg [7:0] rx0_drop_cnt; -reg [7:0] rx1_drop_cnt; - -reg [3:0] bit_cnt; -reg [3:0] addr; - -always @(posedge clk or negedge rstn) - if (!rstn) begin - bit_cnt <= 4'h0; - addr <= 4'h0; - end - else if ( metrics_start ) begin - bit_cnt <= 4'h0; - addr <= 4'h0; - end - else if ( !mode_100Mbit || ( mode_100Mbit && bit_cnt == 4'h9 ) ) begin - bit_cnt <= 4'h0; - addr <= addr + 1; - end - else - bit_cnt <= bit_cnt + 1; - -always @(posedge clk or negedge rstn) - if (!rstn) - rx_pkt_cnt <= 'h0; - else if (rx_eop[2]) - rx_pkt_cnt <= rx_pkt_cnt + 1; - -always @(posedge clk or negedge rstn) - if (!rstn) - tx_pkt_cnt <= 'h0; - else if (tx_eop[2]) - tx_pkt_cnt <= tx_pkt_cnt + 1; - -always @(posedge clk or negedge rstn) - if (!rstn) - metrics_d <= 9'h100; - else begin - case(addr) - 'h0: metrics_d <= { 1'b0, rx_pkt_cnt }; - 'h1: metrics_d <= { 1'b0, tx_pkt_cnt }; - 'h2: metrics_d <= { 1'b0, rx0_drop_cnt }; - 'h3: metrics_d <= { 1'b1, rx1_drop_cnt }; - default: metrics_d <= 9'h100; - endcase - end - - - -endmodule diff --git a/source/pkt_filter.v b/source/pkt_filter.v deleted file mode 100644 index 9140c74..0000000 --- a/source/pkt_filter.v +++ /dev/null @@ -1,95 +0,0 @@ -/* - * pkt_filter.v - * - * Copyright 2018, 2019, 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: packet filter / CAM wrapper with keep / drop logic - * - */ - -`timescale 1ns /10ps - -module pkt_filter #(parameter DEPTH = 4, - parameter DEPTHW = 2, - parameter WIDTH = 32) -( - input rstn, - input clk, - - // input for programming - input sel, - input we, - input [DEPTHW+1:0] addr, - input [7:0] d_in, - - // registered data - input[7:0] rx_data_m1, - input[7:0] rx_data_m2, - input[7:0] rx_data_m3, - input[7:0] rx_data_m4, - - // filter - input new_frame, // assert for each new frame to reset state machines - input block, - input invert, - input trigger, - output reg keep -); - -reg trigger_m1; -wire match; - - -/* trigger_m1 is used to sync the CAM search with testing the results below */ -always @(posedge clk or negedge rstn) - if (!rstn) - trigger_m1 <= 1'b0; - else - trigger_m1 <= trigger; - -/* keep is a one shot */ -always @(posedge clk or negedge rstn) - if (!rstn) - keep <= 1'b0; - else if (trigger_m1) - if ( block ) - keep <= 1'b0; - else if ( !invert ) - keep <= match; - else begin - keep <= ~match; - end - else - keep <= 1'b0; - -cam #(.DEPTH(DEPTH), .DEPTHW(DEPTHW), .WIDTH(WIDTH)) cam_0( - .rstn( rstn ), - .clk( clk ), - - // input for programming - .sel( sel ), - .we( we ), - .addr( addr ), - .d_in( d_in ), - // cam action - .search( trigger ), - .search_address( { rx_data_m4, rx_data_m3, rx_data_m2, rx_data_m1 } ), - .match( match ) -); - - - -endmodule - diff --git a/source/sgmii_params.v b/source/sgmii_params.v deleted file mode 100644 index a36160e..0000000 --- a/source/sgmii_params.v +++ /dev/null @@ -1,55 +0,0 @@ -/* - * sgmii_params.v - * - * Copyright 2018, 2019, 2020 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: SGMII Related Parameters - * - */ - - -/* SGMII Speed Bits [11:10] */ - -localparam SGMII_SPEED_10MBIT = 2'b00, - SGMII_SPEED_100MBIT = 2'b01, - SGMII_SPEED_1GBIT = 2'b10, - SGMII_SPEED_RSVD = 2'b11, - SGMII_SPEED_AN = 2'b11; - -/* - * Notes about K Codes: - * Start of Packet: /S/, K27.7, 0xFB - * End of Packet: /T/, K23.7, 0xF7 - * - */ -localparam D2_2 = 8'h42, - D2_5 = 8'ha2, - D5_6 = 8'hC5, - D10_2 = 8'h4a, - D16_2 = 8'h50, - D21_5 = 8'hb5, // used in a Config Code Group - - /* Note that these are only K codes if the k bit is asserted */ - K23_7 = 8'hf7, // /R/ Carrier Extend - K27_7 = 8'hfb, // /S/ Start_of_Packet - K28_0 = 8'h1c, - K28_1 = 8'h3c, - K28_2 = 8'h5c, - K28_3 = 8'h7c, - K28_4 = 8'h9c, - K28_5 = 8'hbc, - K28_6 = 8'hdc, - K29_7 = 8'hfd, // /T/ End_of_Packet - K_ERROR = 8'hee; diff --git a/source/spi.v b/source/spi.v deleted file mode 100644 index d7c054b..0000000 --- a/source/spi.v +++ /dev/null @@ -1,315 +0,0 @@ -/* - * spi.v - * - * Copyright (C) 2018, 2019, 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: SPI slave controller - * - * refer to SPI protocol figure at https://mindchasers.com/dev/hw-spi - * - */ - -`timescale 1ns /10ps - - module spi( - input rstn, - input clk, - - // SPI signals - input spi_cs, - input spi_clk, - input spi_d_in, - output reg spi_d_o, - output spi_d_oe, - - // internal FPGA memory interface - output [10:0] mem_addr, - output [4:0] mux_sel, - input [8:0] d_i, // data out of FPGA memories - output reg [8:0] d_o, // data into FPGA memories - - // individual memory selects - output reg we, - output oe, - output reg dpram_tx_sel, - output reg dpram_rx_sel, - output reg dpram_ptrs_sel, - output reg [3:0] param_sel, - output reg pkt_filter_sel_01, - output reg pkt_filter_sel_02, - output reg pkt_filter_sel_03, - output reg pkt_filter_sel_10, - output reg pkt_filter_sel_12, - output reg pkt_filter_sel_13, - output reg pkt_filter_sel_20, - output reg pkt_filter_sel_21, - output reg pkt_filter_sel_23, - output reg pkt_filter_sel_2u, - output reg pkt_filter_sel_30, - output reg pkt_filter_sel_31, - output reg pkt_filter_sel_32, - output reg pkt_filter_sel_u2, - output reg interrupts_sel, - output reg[1:0] sci_sel_dual, - output reg[3:0] sci_sel_ch - ); - - localparam start_code = 9'h76; - - wire bit_cnt_rstn; // async reset at start of SPI cycle - - reg spi_clk_m1, spi_clk_m2; // detect / debounce the SPI CLK - reg spi_clk_high, spi_clk_high_m1; // one shot clocks for sequencing events - reg spi_clk_low, spi_clk_low_m1; // one shot clocks for sequencing events - - reg [4:0] bit_cnt; // cnt the bits - reg [6:0] word_cnt; // number of bytes transferred, OK to roll over - - // capture these from SPI bus - reg [7:0] dev_ad; // device address - reg rwn; // follows address - reg [8:0] addr; // address - - wire mem_sel, pkt_filter_sel; // - - // async reset at the start of each SPI transfer - assign bit_cnt_rstn = spi_cs & rstn; - - // debounce and capture the asynch spi_clk - always @(posedge clk or negedge bit_cnt_rstn) - begin - if ( !bit_cnt_rstn ) begin - spi_clk_m1 <= 1'b0; - spi_clk_m2 <= 1'b0; - end - else if ( spi_cs ) begin - spi_clk_m1 <= spi_clk; - spi_clk_m2 <= spi_clk_m1; - end - end - - // create two seq one shots for actions - always @(posedge clk or negedge bit_cnt_rstn) - begin - if ( !bit_cnt_rstn ) - spi_clk_high <= 0; - else if ( spi_cs && spi_clk && spi_clk_m1 && !spi_clk_m2 ) - spi_clk_high <= 1'b1; - else - spi_clk_high <= 1'b0; - end - - always @(posedge clk or negedge bit_cnt_rstn) - begin - if ( !bit_cnt_rstn ) - spi_clk_high_m1 <= 0; - else - spi_clk_high_m1 <= spi_clk_high; - end - - - // create two seq one shots for actions - always @(posedge clk or negedge bit_cnt_rstn) - begin - if ( !bit_cnt_rstn ) - spi_clk_low <= 0; - else if ( spi_cs && spi_clk && !spi_clk_m1 && spi_clk_m2 ) - spi_clk_low <= 1'b1; - else - spi_clk_low <= 1'b0; - end - - always @(posedge clk or negedge bit_cnt_rstn) - begin - if ( !bit_cnt_rstn ) - spi_clk_low_m1 <= 0; - else - spi_clk_low_m1 <= spi_clk_low; - end - - /* - bit_cnt indicates the state of the SPI transfer - - 0:7: dev_ad - 8: rwn - 9:17: addr - 18:26: data (repeats) - */ - always @(posedge clk or negedge bit_cnt_rstn) - begin - if ( !bit_cnt_rstn ) - bit_cnt <= 5'h0; - else if ( spi_cs && spi_clk_high_m1 ) begin - if ( bit_cnt == 5'd26 ) - bit_cnt <= 5'd18; - else - bit_cnt <= bit_cnt + 1; - end - end - - // word_cnt - always @(posedge clk or negedge bit_cnt_rstn) - begin - if (!bit_cnt_rstn) - word_cnt <= 0; - else if ( spi_cs && spi_clk_high && bit_cnt == 5'd26 ) - word_cnt <= word_cnt + 1; - end - - /* Logic to capture common dev_ad, rwn, and address */ - - // capture dev_ad - always @(posedge clk or negedge bit_cnt_rstn) - begin - if ( !bit_cnt_rstn ) - dev_ad <= 'h0; - else if ( spi_cs && spi_clk_high && bit_cnt < 5'd8 ) - dev_ad <= { dev_ad[6:0], spi_d_in }; - end - - // capture rwn bit - always @(posedge clk or negedge bit_cnt_rstn) - begin - if ( !bit_cnt_rstn ) - rwn <= 1'b1; - else if ( spi_cs && spi_clk_high && bit_cnt == 5'd8 ) - rwn <= spi_d_in; - end - - // capture addr - always @(posedge clk or negedge bit_cnt_rstn) - begin - if (!bit_cnt_rstn) - addr <= 'h0; - else if (spi_cs ) begin - if ( spi_clk_high && bit_cnt >= 5'd9 && bit_cnt <= 5'd17 ) - addr <= { addr[7:0], spi_d_in }; - // delay advancing addr until write completes - else if ( spi_clk_high_m1 && bit_cnt == 5'd26 ) - addr <= addr + 1; - end - end - - assign mem_addr = { dev_ad[1:0], addr }; - - /* Logic for write data into FPGA */ - - // capture write data - always @(posedge clk or negedge bit_cnt_rstn) - begin - if (!bit_cnt_rstn) - d_o <= 8'h0; - else if (spi_cs && spi_clk_high && !rwn && bit_cnt >= 5'd18) - d_o <= { d_o[7:0], spi_d_in }; - end - - // we - always @(posedge clk or negedge bit_cnt_rstn) - if (!bit_cnt_rstn) - we <= 1'b0; - else if ( spi_cs ) - if ( spi_clk_high && !rwn && bit_cnt == 5'd26 ) - we <= 1'b1; - else - we <= 1'b0; - - /* SPI data output enable */ - assign spi_d_oe = spi_cs; - - - /* - * clock out msb first. - * - */ - always @(posedge clk or negedge bit_cnt_rstn) - if ( !bit_cnt_rstn ) - spi_d_o <= start_code[8]; - else if ( spi_cs && spi_clk_high_m1 ) begin - if ( bit_cnt < 9 ) - spi_d_o <= start_code['d8 - bit_cnt[3:0]]; - else if ( !rwn && bit_cnt >= 'd18 && bit_cnt < 'd26 ) - spi_d_o <= word_cnt['d25-bit_cnt]; - else if ( rwn && bit_cnt >= 'd18 && bit_cnt < 'd26 ) - spi_d_o <= d_i['d25-bit_cnt]; - else - spi_d_o <= 1'b0; - end - else if (spi_cs && spi_clk_high_m1 && rwn && bit_cnt == 'd26) - spi_d_o <= d_i[8]; - - assign oe = mem_sel && rwn; - - /* Address Decoding */ - assign pkt_filter_sel = pkt_filter_sel_01 | pkt_filter_sel_02 | pkt_filter_sel_10 | pkt_filter_sel_12 | - pkt_filter_sel_20 | pkt_filter_sel_21 | pkt_filter_sel_23; - - assign mem_sel = dpram_rx_sel | dpram_tx_sel | dpram_ptrs_sel | pkt_filter_sel | param_sel[0] | - param_sel[1] | param_sel[2] | param_sel[2] | interrupts_sel; - - - // use to steer data into this module - assign mux_sel = dev_ad[6:2]; - - // address decode - always @(*) - begin - sci_sel_dual = 2'b00; - sci_sel_ch = 4'b000; - dpram_rx_sel = 1'b0; - dpram_tx_sel = 1'b0; - dpram_ptrs_sel = 1'b0; - pkt_filter_sel_01 = 1'b0; - pkt_filter_sel_02 = 1'b0; - pkt_filter_sel_10 = 1'b0; - pkt_filter_sel_12 = 1'b0; - pkt_filter_sel_20 = 1'b0; - pkt_filter_sel_21 = 1'b0; - pkt_filter_sel_23 = 1'b0; - param_sel = 4'b0000; - interrupts_sel = 1'b0; - casez( dev_ad[7:0] ) - 8'b00000000: sci_sel_ch = 4'b0001; // sgmii0 - 8'b00000001: sci_sel_ch = 4'b0010; // sgmii1 - 8'b00000010: sci_sel_dual = 2'b01; // DCU0 Dual - 8'b00000100: sci_sel_ch = 4'b0100; // sgmii2 - 8'b00000101: sci_sel_ch = 4'b1000; // sgmii3 - 8'b00000110: sci_sel_dual = 2'b10; // DCU1 Dual - 8'b000010??: dpram_rx_sel = 1'b1; - 8'b000011??: dpram_tx_sel = 1'b1; - 8'b00010000: dpram_ptrs_sel = 1'b1; - 8'b00010001: interrupts_sel = 1'b1; - 8'b001000??: param_sel[0] = 1'b1; - 8'b001001??: param_sel[1] = 1'b1; - 8'b001010??: param_sel[2] = 1'b1; - 8'b001011??: param_sel[3] = 1'b1; - 8'b01000001: pkt_filter_sel_01 = 1'b1; - 8'b01000010: pkt_filter_sel_02 = 1'b1; - 8'b01000011: pkt_filter_sel_03 = 1'b1; - 8'b01001000: pkt_filter_sel_10 = 1'b1; - 8'b01001010: pkt_filter_sel_12 = 1'b1; - 8'b01001011: pkt_filter_sel_13 = 1'b1; - 8'b01010000: pkt_filter_sel_20 = 1'b1; - 8'b01010001: pkt_filter_sel_21 = 1'b1; - 8'b01010011: pkt_filter_sel_23 = 1'b1; - 8'b01010111: pkt_filter_sel_2u = 1'b1; - 8'b01011000: pkt_filter_sel_30 = 1'b1; - 8'b01011001: pkt_filter_sel_31 = 1'b1; - 8'b01011010: pkt_filter_sel_32 = 1'b1; - 8'b01111010: pkt_filter_sel_u2 = 1'b1; - endcase - end - - endmodule - \ No newline at end of file diff --git a/source/switch.v b/source/switch.v deleted file mode 100644 index 98aec4a..0000000 --- a/source/switch.v +++ /dev/null @@ -1,531 +0,0 @@ -/* - * switch.v - * - * Copyright 2018, 2019, 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: Soft Ethernet Switch - * - */ - -`timescale 1ns /10ps - -module switch( - input rstn, - input clk, - - // PHY status - input [3:0] phy_up, - input [3:0] mode_100Mbit, - - // FIFO input data from RX FIFOs - input [8:0] rx_d_01, - input [8:0] rx_d_02, - input [8:0] rx_d_03, - input [8:0] rx_d_10, - input [8:0] rx_d_12, - input [8:0] rx_d_13, - input [8:0] rx_d_20, - input [8:0] rx_d_21, - input [8:0] rx_d_23, - input [8:0] rx_d_2u, - input [8:0] rx_d_30, - input [8:0] rx_d_31, - input [8:0] rx_d_32, - input [8:0] rx_d_u2, - - // RX FIFO read enables - output reg rx_fifo_re_01, rx_fifo_re_02, rx_fifo_re_03, - output reg rx_fifo_re_10, rx_fifo_re_12, rx_fifo_re_13, - output reg rx_fifo_re_20, rx_fifo_re_21, rx_fifo_re_23, rx_fifo_re_2u, - output reg rx_fifo_re_30, rx_fifo_re_31, rx_fifo_re_32, - output reg rx_fifo_re_u2, - - // RX FIFO Empty flags - input rx_fifo_empty_01, rx_fifo_empty_02, rx_fifo_empty_03, - input rx_fifo_empty_10, rx_fifo_empty_12, rx_fifo_empty_13, - input rx_fifo_empty_20, rx_fifo_empty_21, rx_fifo_empty_23, rx_fifo_empty_2u, - input rx_fifo_empty_30, rx_fifo_empty_31, rx_fifo_empty_32, - input rx_fifo_empty_u2, - - // RX Byte Count - input [3:0] rx_wr_done, - input [10:0] rx0_byte_cnt, - input [10:0] rx1_byte_cnt, - input [10:0] rx2_byte_cnt, - input [10:0] rx3_byte_cnt, - - // TX FIFO output from internal muxes - output reg [8:0] tx_d0, - output reg [8:0] tx_d1, - output reg [8:0] tx_d2, - output reg [8:0] tx_d3, - output [8:0] tx_du, - - // TX FIFO read enable inputs (need to route to RX output FIFOs) - input [3:0] tx_fifo_re, - output reg tx_fifo_we_u, - - // TX FIFO Empty Flags (need to route to RX output FIFOs) - output reg [3:0] tx_fifo_empty, - - // TX modes for the PHYs and uc - output reg [2:0] tx_mode0, - output reg [2:0] tx_mode1, - output reg [2:0] tx_mode2, - output reg [2:0] tx_mode3, - output reg tx_modeu, - - // TX byte cnt - output reg [10:0] tx0_byte_cnt, - output reg [10:0] tx1_byte_cnt, - output reg [10:0] tx2_byte_cnt, - output reg [10:0] tx3_byte_cnt, - - // TX Source Select - output reg [2:0] tx_src_sel0, - output reg [2:0] tx_src_sel1, - output reg [2:0] tx_src_sel2, - output reg [2:0] tx_src_sel3, - - // TX state machine done flag - input [3:0] tx_f, - - // TX custom packet - input tx_custom -); - -// IPG for Port 0 -wire ipg_met; -reg [6:0] ipg_cnt; -reg [3:0] fr_100mbit_cnt; - -reg i_tx_fifo_we_u; - -reg [10:0] i_rx0_byte_cnt, i_rx1_byte_cnt, i_rx2_byte_cnt, i_rx3_byte_cnt; - -`include "ethernet_params.v" -`include "sgmii_params.v" - -localparam SEL_PHY0 = 3'b000, - SEL_PHY1 = 3'b001, - SEL_PHY2 = 3'b010, - SEL_PHY3 = 3'b011, - SEL_UC = 3'b111; - - -// capture the rx_byte_cnt values when write is done. TODO: needs to be a shallow Q to match FIFO -always @(posedge clk, negedge rstn) - if ( !rstn ) - i_rx0_byte_cnt <= 'h0; - else if ( rx_wr_done[0]) - i_rx0_byte_cnt <= rx0_byte_cnt; - -always @(posedge clk, negedge rstn) - if ( !rstn ) - i_rx1_byte_cnt <= 'h0; - else if ( rx_wr_done[1]) - i_rx1_byte_cnt <= rx1_byte_cnt; - -always @(posedge clk, negedge rstn) - if ( !rstn ) - i_rx2_byte_cnt <= 'h0; - else if ( rx_wr_done[2]) - i_rx2_byte_cnt <= rx2_byte_cnt; - -always @(posedge clk, negedge rstn) - if ( !rstn ) - i_rx3_byte_cnt <= 'h0; - else if ( rx_wr_done[3]) - i_rx3_byte_cnt <= rx3_byte_cnt; - -assign ipg_met = ipg_cnt >= IPG ? 1'b1 : 1'b0; - -/* free running 100Mbit counter */ -always @(posedge clk, negedge rstn) - if ( !rstn ) - fr_100mbit_cnt <= 4'd0; - else if ( fr_100mbit_cnt == 4'd9 ) - fr_100mbit_cnt <= 4'd0; - else - fr_100mbit_cnt <= fr_100mbit_cnt + 1; - -/* IPG counter */ -always @(posedge clk, negedge rstn) - if ( !rstn ) - ipg_cnt <= 7'd0; - else if ( tx_f[0] && tx_mode0 >= TX_MODE_XMT_PKT ) - ipg_cnt <= 7'd0; - else if ( mode_100Mbit[0] && fr_100mbit_cnt == 4'd9 && !ipg_met ) - ipg_cnt <= ipg_cnt + 1; - else if ( !mode_100Mbit[0] && !ipg_met ) - ipg_cnt <= ipg_cnt + 1; - - -// TX0 Switch Logic -// Possible sources: 1, 2 -always @(posedge clk, negedge rstn) - if ( !rstn ) - begin - tx_mode0 <= TX_MODE_AN; - tx_src_sel0 <= SEL_PHY1; - tx0_byte_cnt <= 'h0; - end - else if ( tx_f[0] ) - case( tx_mode0 ) - TX_MODE_AN: - if ( phy_up[0] ) - tx_mode0 <= TX_MODE_IDLE; - TX_MODE_IDLE: - if ( !phy_up[0] ) - tx_mode0 <= TX_MODE_AN; - else if ( !ipg_met ) - tx_mode0 <= TX_MODE_IDLE; - else if (tx_src_sel0==SEL_PHY1 && !rx_fifo_empty_20 ) - begin - tx_mode0 <= TX_MODE_XMT_CUSTOM; - tx_src_sel0 <= SEL_PHY2; - tx0_byte_cnt <= i_rx2_byte_cnt; - end - else if (!rx_fifo_empty_10 ) - begin - tx_mode0 <= TX_MODE_XMT_PKT; - tx_src_sel0 <= SEL_PHY1; - tx0_byte_cnt <= i_rx1_byte_cnt; - end - else if (!rx_fifo_empty_20 ) - begin - tx_mode0 <= TX_MODE_XMT_CUSTOM; - tx_src_sel0 <= SEL_PHY2; - tx0_byte_cnt <= i_rx2_byte_cnt; - end - TX_MODE_XMT_PKT: - if ( !phy_up[0] ) - tx_mode0 <= TX_MODE_AN; - else - tx_mode0 <= TX_MODE_IDLE; - default: tx_mode0 <= TX_MODE_IDLE; - endcase - -// TX0 data mux -always @(*) begin - case(tx_src_sel0) - SEL_PHY0: tx_d0 = 9'h000; - SEL_PHY1: tx_d0 = rx_d_10; - SEL_PHY2: tx_d0 = rx_d_20; - SEL_UC: tx_d0 = 9'h000; - default: tx_d0 = 9'h000; - endcase -end - -// TX0 FIFO read enable -always @(*) begin - rx_fifo_re_10 = 1'b0; - rx_fifo_re_20 = 1'b0; - rx_fifo_re_30 = 1'b0; - case(tx_src_sel0) - SEL_PHY1: rx_fifo_re_10 = tx_fifo_re[0]; - SEL_PHY2: rx_fifo_re_20 = tx_fifo_re[0]; - SEL_PHY3: rx_fifo_re_30 = tx_fifo_re[0]; - endcase -end - -// TX0 FIFO Empty Routing -always @(*) begin - case(tx_src_sel0) - SEL_PHY1: tx_fifo_empty[0] = rx_fifo_empty_10; - SEL_PHY2: tx_fifo_empty[0] = rx_fifo_empty_20; - SEL_PHY3: tx_fifo_empty[0] = rx_fifo_empty_30; - default: tx_fifo_empty[0] = 1'b1; - endcase -end - -// TX1 Switch Logic -// Possible sources: 0, 2, 3 in priority -always @(posedge clk, negedge rstn) - if ( !rstn ) - begin - tx_mode1 <= TX_MODE_AN; - tx_src_sel1 <= SEL_PHY0; - end - else if ( tx_f[1] ) - case( tx_mode1 ) - TX_MODE_AN: - if ( phy_up[1] ) - tx_mode1 <= TX_MODE_IDLE; - TX_MODE_IDLE: - if ( !phy_up[1] ) - tx_mode1 <= TX_MODE_AN; - else if (tx_src_sel1==SEL_PHY0 && !rx_fifo_empty_21 ) - begin - tx_mode1 <= TX_MODE_XMT_PKT; - tx_src_sel1 <= SEL_PHY2; - end - else if (tx_src_sel1==SEL_PHY0 && !rx_fifo_empty_31 ) - begin - tx_mode1 <= TX_MODE_XMT_PKT; - tx_src_sel1 <= SEL_PHY3; - end - else if (!rx_fifo_empty_01 ) - begin - tx_mode1 <= TX_MODE_XMT_PKT; - tx_src_sel1 <= SEL_PHY0; - end - else if (!rx_fifo_empty_21 ) - begin - tx_mode1 <= TX_MODE_XMT_PKT; - tx_src_sel1 <= SEL_PHY2; - end - else if (!rx_fifo_empty_31 ) - begin - tx_mode1 <= TX_MODE_XMT_PKT; - tx_src_sel1 <= SEL_PHY3; - end - TX_MODE_XMT_PKT: - if ( !phy_up[1] ) - tx_mode1 <= TX_MODE_AN; - else - tx_mode1 <= TX_MODE_IDLE; - default: tx_mode1 <= TX_MODE_IDLE; - endcase - -// TX1 data mux -always @(*) begin - case(tx_src_sel1) - SEL_PHY0: tx_d1 = rx_d_01; - SEL_PHY1: tx_d1 = 9'h000; - SEL_PHY2: tx_d1 = rx_d_21; - SEL_PHY3: tx_d1 = rx_d_31; - SEL_UC: tx_d1 = 9'h000; - default: tx_d1 = 9'h000; - endcase -end - -// TX1 FIFO read enable -always @(*) begin - rx_fifo_re_01 = 1'b0; - rx_fifo_re_21 = 1'b0; - rx_fifo_re_31 = 1'b0; - case(tx_src_sel1) - SEL_PHY0: rx_fifo_re_01 = tx_fifo_re[1]; - SEL_PHY2: rx_fifo_re_21 = tx_fifo_re[1]; - SEL_PHY3: rx_fifo_re_31 = tx_fifo_re[1]; - endcase -end - -// TX1 FIFO Empty Routing -always @(*) begin - case(tx_src_sel1) - SEL_PHY0: tx_fifo_empty[1] = rx_fifo_empty_01; - SEL_PHY1: tx_fifo_empty[1] = 1'b1; - SEL_PHY2: tx_fifo_empty[1] = rx_fifo_empty_21; - SEL_PHY3: tx_fifo_empty[1] = rx_fifo_empty_31; - SEL_UC: tx_fifo_empty[1] = 1'b1; - default: tx_fifo_empty[1] = 1'b1; - endcase -end - - -/* - * TX2 Switch Logic - * Possible Sources: 0, 1, UC - * Note that for TX_MODE_XMT_METRICS, we set the source to be loopback, but it is expected that the - * phy controller will use a combination of local memory and the metrics block for its data. These decisions - * should be revisited when implementing loopback within this switch module. - */ -always @(posedge clk, negedge rstn) - if ( !rstn ) - begin - tx_mode2 <= TX_MODE_AN; - tx_src_sel2 <= SEL_PHY0; - end - else if ( tx_f[2] ) - case( tx_mode2 ) - TX_MODE_AN: - if ( phy_up[2] ) - tx_mode2 <= TX_MODE_IDLE; - TX_MODE_IDLE: - if ( !phy_up[2] ) - tx_mode2 <= TX_MODE_AN; - else if (tx_src_sel2==SEL_PHY0 && !rx_fifo_empty_12 ) - begin - tx_mode2 <= TX_MODE_XMT_PKT; - tx_src_sel2 <= SEL_PHY1; - end - else if (!rx_fifo_empty_02 ) - begin - tx_mode2 <= TX_MODE_XMT_PKT; - tx_src_sel2 <= SEL_PHY0; - end - else if (!rx_fifo_empty_12 ) - begin - tx_mode2 <= TX_MODE_XMT_PKT; - tx_src_sel2 <= SEL_PHY1; - end - else if (!rx_fifo_empty_u2) - begin - tx_mode2 <= TX_MODE_XMT_PKT; - tx_src_sel2 <= SEL_UC; - end - else if (tx_custom) - begin - tx_mode2 <= TX_MODE_XMT_CUSTOM; - tx_src_sel2 <= SEL_PHY2; - end - TX_MODE_XMT_PKT: - if ( !phy_up[2] ) - tx_mode2 <= TX_MODE_AN; - else - tx_mode2 <= TX_MODE_IDLE; - default: tx_mode2 <= TX_MODE_IDLE; - endcase - -// TX2 data mux -always @(*) begin - case(tx_src_sel2) - SEL_PHY0: tx_d2 = rx_d_02; - SEL_PHY1: tx_d2 = rx_d_12; - SEL_PHY2: tx_d2 = 9'h000; - SEL_UC: tx_d2 = rx_d_u2; - default: tx_d2 = 9'h000; - endcase -end - -// TX2 FIFO read enable -always @(*) begin - rx_fifo_re_02 = 1'b0; - rx_fifo_re_12 = 1'b0; - rx_fifo_re_u2 = 1'b0; - case(tx_src_sel2) - SEL_PHY0: rx_fifo_re_02 = tx_fifo_re[2]; - SEL_PHY1: rx_fifo_re_12 = tx_fifo_re[2]; - SEL_UC: rx_fifo_re_u2 = tx_fifo_re[2]; - endcase -end - -// TX2 FIFO Empty Routing -always @(*) begin - case(tx_src_sel2) - SEL_PHY0: tx_fifo_empty[2] = rx_fifo_empty_02; - SEL_PHY1: tx_fifo_empty[2] = rx_fifo_empty_12; - SEL_PHY2: tx_fifo_empty[2] = 1'b0; // - SEL_UC: tx_fifo_empty[2] = rx_fifo_empty_u2; - default: tx_fifo_empty[2] = 1'b1; - endcase -end - - -// TX3 Switch Logic -// Possible sources: 0, 1 -always @(posedge clk, negedge rstn) - if ( !rstn ) - begin - tx_mode3 <= TX_MODE_AN; - tx_src_sel3 <= SEL_PHY1; - end - else if ( tx_f[3] ) - case( tx_mode3 ) - TX_MODE_AN: - if ( phy_up[3] ) - tx_mode3 <= TX_MODE_IDLE; - TX_MODE_IDLE: - if ( !phy_up[3] ) - tx_mode3 <= TX_MODE_AN; - else if (tx_src_sel3==SEL_PHY1 && !rx_fifo_empty_03 ) - begin - tx_mode3 <= TX_MODE_XMT_PKT; - tx_src_sel3 <= SEL_PHY0; - end - else if (!rx_fifo_empty_13 ) - begin - tx_mode3 <= TX_MODE_XMT_PKT; - tx_src_sel3 <= SEL_PHY1; - end - else if (!rx_fifo_empty_03 ) - begin - tx_mode3 <= TX_MODE_XMT_PKT; - tx_src_sel3 <= SEL_PHY0; - end - TX_MODE_XMT_PKT: - if ( !phy_up[3] ) - tx_mode3 <= TX_MODE_AN; - else - tx_mode3 <= TX_MODE_IDLE; - default: tx_mode3 <= TX_MODE_IDLE; - endcase - - // TX3 data mux - always @(*) begin - case(tx_src_sel3) - SEL_PHY0: tx_d3 = rx_d_03; - SEL_PHY1: tx_d3 = rx_d_13; - SEL_PHY2: tx_d3 = rx_d_23; - SEL_PHY3: tx_d3 = 9'h000; - SEL_UC: tx_d3 = 9'h000; - default: tx_d3 = 9'h000; - endcase - end - - // TX3 FIFO read enable - always @(*) begin - rx_fifo_re_03 = 1'b0; - rx_fifo_re_13 = 1'b0; - rx_fifo_re_23 = 1'b0; - case(tx_src_sel3) - SEL_PHY0: rx_fifo_re_03 = tx_fifo_re[3]; - SEL_PHY1: rx_fifo_re_13 = tx_fifo_re[3]; - SEL_PHY2: rx_fifo_re_23 = tx_fifo_re[3]; - endcase - end - - // TX3 FIFO Empty Routing - always @(*) begin - case(tx_src_sel3) - SEL_PHY0: tx_fifo_empty[3] = rx_fifo_empty_03; - SEL_PHY1: tx_fifo_empty[3] = rx_fifo_empty_13; - SEL_PHY2: tx_fifo_empty[3] = rx_fifo_empty_23; - default: tx_fifo_empty[3] = 1'b1; - endcase - end - -/* - * Transmit Logic for UC - * - * The only possible driver is PHY2 - * - * We need to delay the fifo_we one clock since the DPRAM read data comes out one clock delayed - */ - -assign tx_du = rx_d_2u; - -always @(*) - if ( !rx_fifo_empty_2u ) - begin - i_tx_fifo_we_u = 1'b1; - rx_fifo_re_2u = 1'b1; - end - else - begin - i_tx_fifo_we_u = 1'b0; - rx_fifo_re_2u = 1'b0; - end - -always @(posedge clk, negedge rstn) - if ( !rstn ) - tx_fifo_we_u <= 1'b0; - else - tx_fifo_we_u <= i_tx_fifo_we_u; - - -endmodule diff --git a/source/sync_fifo.v b/source/sync_fifo.v deleted file mode 100644 index 56c83d4..0000000 --- a/source/sync_fifo.v +++ /dev/null @@ -1,110 +0,0 @@ -/* - * sync_fifo.v - * - * Copyright (C) 2018, 2019 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: FIFO / data store between RX and TX for each path - * - */ - -`timescale 1ns /10ps - -module sync_fifo #(parameter FIFO_PTR = 11, - FIFO_WIDTH = 9, - FIFO_DEPTH = 2048 ) -( - input rstn, - input clk, - - - // input - input we, - input [FIFO_WIDTH-1:0] d_in, - - // output - input re, - output [FIFO_WIDTH-1:0] d_out, - output empty, - output almost_full, - - // fifo_control - input reset_ptrs, - - // debug - output active - -); - -`include "ethernet_params.v" - -reg [FIFO_PTR-1:0] wr_ptr; -reg [FIFO_PTR-1:0] rd_ptr; -reg [FIFO_PTR-1:0] wr_bytes_available; // use for size calculation below - - -always @(posedge clk, negedge rstn) - if( !rstn ) - wr_ptr <= 'd0; - else if ( reset_ptrs ) - wr_ptr <= 'd0; - else if ( we ) - wr_ptr <= wr_ptr + 1; - -/* - * rd_ptr - * use empty flat to make sure rd_ptr doesn't advance when empty ( error condition ) - */ -always @(posedge clk, negedge rstn) - if( !rstn ) - rd_ptr <= 'd0; - else if ( reset_ptrs ) - rd_ptr <= 'd0; - else if ( re && !empty ) - rd_ptr <= rd_ptr + 1; - -assign empty = ( rd_ptr == wr_ptr ) ? 1'b1 : 1'b0; -assign almost_full = wr_bytes_available < MTU ? 1'b1 : 1'b0; - -always @(posedge clk, negedge rstn) - if( !rstn ) - wr_bytes_available <= FIFO_DEPTH-1; - else if ( wr_ptr >= rd_ptr ) - wr_bytes_available <= FIFO_DEPTH-1 - (wr_ptr - rd_ptr); - else - wr_bytes_available <= rd_ptr - wr_ptr; - -assign active = ~empty; - - -dpram dpram_fifo( - .rstn( rstn ), - .a_clk( clk ), - .a_clk_e( 1'b1 ), - .a_we( we ), - .a_oe( 1'b0 ), - .a_addr( wr_ptr ), - .a_din( d_in ), - .a_dout( ), - // port B - .b_clk( clk ), - .b_clk_e( re ), - .b_we( 1'b0 ), - .b_oe( re ), - .b_addr( rd_ptr ), - .b_din( 9'h0 ), - .b_dout( d_out ) -); - -endmodule -- cgit v1.2.3-8-gadcc