summaryrefslogtreecommitdiffhomepage
path: root/src/controller.v
diff options
context:
space:
mode:
Diffstat (limited to 'src/controller.v')
-rw-r--r--src/controller.v136
1 files changed, 78 insertions, 58 deletions
diff --git a/src/controller.v b/src/controller.v
index 54d6976..e30d461 100644
--- a/src/controller.v
+++ b/src/controller.v
@@ -1,5 +1,5 @@
/*
- * controller.v
+ * controller.v
*
* Copyright (C) 2023-2025 Private Island Networks Inc.
* Copyright (C) 2018-2022 Mind Chasers Inc.
@@ -18,8 +18,7 @@
*
* function: FPGA internal state machine controller
*
- * see https://privateisland.tech/dev/pi-doc for further details
- *
+ * see https://privateisland.tech/dev/pi-controller for further details
*
*/
@@ -35,18 +34,20 @@ module controller #(parameter MDIO_ADDR_SZ = 7, parameter NUM_PHYS=3)
// link status
input [NUM_PHYS-1:0] phy_up,
- // Memory Controller bus
+ // Memory Controller I/F
output reg mem_we,
output mem_oe,
output reg [15:0] mem_addr,
output reg[31:0] mem_d_o,
input [31:0] mem_d_i,
+ input mem_tgt_ready,
// Device selects for Controller peripherals
output reg [1:0] mac_addr,
output reg [15:0] pkt_filter_addr,
output reg pkt_filter_sel,
output reg mac_sel,
+ output reg mle_sel,
output reg hf_ptrs_sel,
output reg hf_tx_sel,
output reg hf_rx_sel,
@@ -88,7 +89,7 @@ module controller #(parameter MDIO_ADDR_SZ = 7, parameter NUM_PHYS=3)
// Version: upper byte is major, lower byte is minor
localparam FW_VERSION_VALUE = 16'h0001;
// Version Increment: Set to 0 when releasing version; otherwise, increment value for each preliminary / trial release
- localparam FW_INCREMENT_VALUE = 16'h0002;
+ localparam FW_INCREMENT_VALUE = 16'h0007;
// Main Controller states
localparam CONT_ST_INIT= 3'h0, CONT_ST_IDLE=3'h1, CONT_ST_START=3'h2, CONT_ST_BUSY=3'h3,
@@ -108,13 +109,14 @@ module controller #(parameter MDIO_ADDR_SZ = 7, parameter NUM_PHYS=3)
localparam MEM_EVENT_NONE=3'h0, MEM_EVENT_FIFO=3'h1;
// Controller Address Space
- localparam FW_VERSION_ADDR = 16'h0000;
- localparam FW_INCREMENT_ADDR = 16'h0004;
- localparam MAC_ADDR = 16'h0010;
- localparam PHY_ADDR = 16'h0014; // Controls mdio_mux_sel, not the MIDO PHY Address
- localparam PKT_FILT_ADDR = 16'h0018;
- localparam RX_MSG_CNT_ADDR = 16'h0020;
- localparam TX_PKT_CNT_ADDR = 16'h0024;
+ localparam
+ FW_VERSION_ADDR = 16'h0000,
+ FW_INCREMENT_ADDR = 16'h0004,
+ MAC_ADDR = 16'h0010,
+ PHY_ADDR = 16'h0014, // Controls mdio_mux_sel, not the MIDO PHY Address
+ PKT_FILT_ADDR = 16'h0018,
+ RX_MSG_CNT_ADDR = 16'h0020,
+ TX_PKT_CNT_ADDR = 16'h0024;
/* Define Variables and Nets Below */
reg [2:0] cont_state;
@@ -137,7 +139,7 @@ module controller #(parameter MDIO_ADDR_SZ = 7, parameter NUM_PHYS=3)
// Command Processing
reg rx_msg_captured;
- reg mdio_cmd, cont_msg;
+ reg mdio_cmd, mem_cmd, cont_msg;
reg [15:0] mdio_d;
// MDIO Init
@@ -150,10 +152,11 @@ module controller #(parameter MDIO_ADDR_SZ = 7, parameter NUM_PHYS=3)
reg [10:0] tx_wr_ptr; // write into the HFIFO TX data
reg rx_rd_active, tx_wr_active;
reg [4:0] rx_cnt, tx_cnt;
+ reg mem_tgt_ready_m1, mem_tgt_ready_m2;
// metrics
reg [15:0] rx_msg_cnt;
- reg [15:0] tx_pkt_cnt;
+ reg [15:0] tx_msg_cnt;
// Synchronize rx_fifo_int
@@ -166,7 +169,18 @@ module controller #(parameter MDIO_ADDR_SZ = 7, parameter NUM_PHYS=3)
rx_fifo_int_m1 <= rx_fifo_int;
rx_fifo_int_m2 <= rx_fifo_int_m1;
end
-
+
+ // Synchronize mem_tgt_ready
+ always @(posedge clk, negedge rstn)
+ if (!rstn) begin
+ mem_tgt_ready_m1 <= 1'b0;
+ mem_tgt_ready_m2 <= 1'b0;
+ end
+ else begin
+ mem_tgt_ready_m1 <= mem_tgt_ready;
+ mem_tgt_ready_m2 <= mem_tgt_ready_m1;
+ end
+
// rx_msg_captured signals a message has been received
always @(posedge clk or negedge rstn)
if (!rstn)
@@ -178,7 +192,6 @@ module controller #(parameter MDIO_ADDR_SZ = 7, parameter NUM_PHYS=3)
// rx_msg_cnt
- // TODO: reset counter by writing the register
always @(posedge clk or negedge rstn)
if (!rstn)
rx_msg_cnt <= 16'd0;
@@ -203,6 +216,8 @@ module controller #(parameter MDIO_ADDR_SZ = 7, parameter NUM_PHYS=3)
CONT_ST_BUSY:
if (cont_msg || msg_error)
cont_state <= CONT_ST_DONE;
+ else if (mem_cmd && mem_tgt_ready_m2)
+ cont_state <= CONT_ST_DONE;
else if (mdio_cmd && mdio_cont_done)
cont_state <= CONT_ST_DONE;
CONT_ST_DONE:
@@ -217,7 +232,7 @@ module controller #(parameter MDIO_ADDR_SZ = 7, parameter NUM_PHYS=3)
cont_msg <= 1'b0;
else if (cont_state == CONT_ST_IDLE && !rx_msg_captured)
cont_msg <= 1'b0;
- else if (rx_msg_captured && (msg_addr[15:8] < MSG_MDIO_ADDR[15:8]))
+ else if (rx_msg_captured && (msg_addr[15:8] == MSG_CONTROLLER_ADDR[15:8]))
cont_msg <= 1'b1;
/***********************************************************************
@@ -293,7 +308,7 @@ module controller #(parameter MDIO_ADDR_SZ = 7, parameter NUM_PHYS=3)
else if (mem_state == MEM_ST_RD_FIFO && rx_cnt == 5'h9 && !msg_addr_valid)
msg_error <= 1'b1;
- // msg data on writes
+ // msg data
always @(posedge clk or negedge rstn)
if (!rstn)
msg_data <= 32'd0;
@@ -309,7 +324,6 @@ module controller #(parameter MDIO_ADDR_SZ = 7, parameter NUM_PHYS=3)
msg_data[7:0] <= mem_d_i[7:0];
// msg_response
- // TODO: add other peripherals
always @(posedge clk, negedge rstn)
if (!rstn)
msg_response <= 16'heeee;
@@ -317,20 +331,25 @@ module controller #(parameter MDIO_ADDR_SZ = 7, parameter NUM_PHYS=3)
msg_response <= 16'heeee;
else if (mem_state == MEM_ST_RD_FIFO_DONE && cont_state == CONT_ST_DONE)
casez (msg_addr)
- FW_VERSION_ADDR : msg_response <= FW_VERSION_VALUE;
+ FW_VERSION_ADDR : msg_response <= FW_VERSION_VALUE;
FW_INCREMENT_ADDR : msg_response <= FW_INCREMENT_VALUE;
MAC_ADDR: msg_response <= mac_addr;
PHY_ADDR: msg_response <= mdio_mux_sel;
PKT_FILT_ADDR: msg_response <= pkt_filter_addr;
- RX_MSG_CNT_ADDR : msg_response <= rx_msg_cnt;
- TX_PKT_CNT_ADDR : msg_response <= tx_pkt_cnt;
- {MSG_MDIO_ADDR[15:8],8'h??}: msg_response <= mdio_d;
+ RX_MSG_CNT_ADDR : msg_response <= rx_msg_cnt;
+ TX_PKT_CNT_ADDR : msg_response <= tx_msg_cnt;
+ {MSG_MAC_ADDR[15:8],8'h??}: msg_response <= mem_d_i;
+ {MSG_MDIO_ADDR[15:8],8'h??}: msg_response <= mdio_d;
+ {MSG_MLE_ADDR[15:8],8'h??}: msg_response <= mem_d_i;
default: msg_response <= mem_d_i[15:0];
endcase
- /*
- * MDIO controller related
- */
+
+/***********************************************************************
+ *
+ * MDIO controller related
+ *
+ **********************************************************************/
// mdio_cmd address decode
always @(posedge clk or negedge rstn)
@@ -368,7 +387,7 @@ module controller #(parameter MDIO_ADDR_SZ = 7, parameter NUM_PHYS=3)
end
// set mdio_phy_addr
- assign mdio_phy_addr = 5'h0c; // Set phy_addr[3:2]
+ assign mdio_phy_addr = 5'h00; // Set phy_addr[3:2]
// set mdio_reg_addr
always @(posedge clk or negedge rstn)
@@ -383,20 +402,18 @@ module controller #(parameter MDIO_ADDR_SZ = 7, parameter NUM_PHYS=3)
/* 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 (mi_state > MI_ST_INIT && mi_state < MI_ST_IDLE) begin
- mdio_w_data_h <= mdio_init_w_data_h;
- mdio_w_data_l <= mdio_init_w_data_l;
- end
- else if (mdio_cmd && msg_type == MSG_TYPE_WRITE) begin
- mdio_w_data_h <= msg_data[15:8];
- mdio_w_data_l <= msg_data[7:0];
- end
- end
+ if (!rstn) begin
+ mdio_w_data_l <= 'd0;
+ mdio_w_data_h <= 'd0;
+ end
+ else if (mi_state > MI_ST_INIT && mi_state < MI_ST_IDLE) begin
+ mdio_w_data_h <= mdio_init_w_data_h;
+ mdio_w_data_l <= mdio_init_w_data_l;
+ end
+ else if (mdio_cmd && msg_type == MSG_TYPE_WRITE) begin
+ mdio_w_data_h <= msg_data[15:8];
+ mdio_w_data_l <= msg_data[7:0];
+ end
// mdio_d, data from MDIO read cycle
always @(posedge clk or negedge rstn)
@@ -410,27 +427,21 @@ module controller #(parameter MDIO_ADDR_SZ = 7, parameter NUM_PHYS=3)
// PHY Reset
always @(posedge clk, negedge rstn)
if (!rstn)
- phy_resetn <= 2'b00;
- else if (1'b0)
- phy_resetn <= 2'b00; // assert reset
+ phy_resetn <= 3'b000;
else
- phy_resetn <= 2'b11;
+ phy_resetn = 3'b111;
// MAC Reset
always @(posedge clk, negedge rstn)
if (!rstn)
- mac_reset <= 2'b11;
- else if (1'b0)
- mac_reset <= 2'b11; // assert reset
+ mac_reset <= 3'b111;
else
- mac_reset <= 2'b00;
+ mac_reset = 3'b000;
/***********************************************************************
*
* Memory Controller and HFIFO Access LAN Controller
*
- * TODO: Review and implement better LAN flow control
- *
**********************************************************************/
// Memory Controller Tie Offs
@@ -468,7 +479,15 @@ module controller #(parameter MDIO_ADDR_SZ = 7, parameter NUM_PHYS=3)
MEM_ST_DONE: mem_state <= MEM_ST_IDLE; // update tx_wr_ptr
default: mem_state <= MEM_ST_IDLE;
endcase
-
+
+ // mem_cmd address decode
+ always @(posedge clk or negedge rstn)
+ if (!rstn)
+ mem_cmd <= 1'b0;
+ else if (cont_state == CONT_ST_IDLE && !rx_msg_captured)
+ mem_cmd <= 1'b0;
+ else if (rx_msg_captured && msg_addr[15:8] >= MSG_MAC_ADDR[15:8] && msg_addr[15:8] < MSG_MLE_ADDR[15:8])
+ mem_cmd <= 1'b1;
// Primary Memory Controller Actions
always @(posedge clk, negedge rstn)
@@ -477,6 +496,7 @@ module controller #(parameter MDIO_ADDR_SZ = 7, parameter NUM_PHYS=3)
mem_d_o <= 32'd0;
mem_addr <= HF_NULL;
mac_sel <= 1'b0;
+ mle_sel <= 1'b0;
pkt_filter_sel <= 1'b0;
hf_ptrs_sel <= 1'b0;
hf_tx_sel <= 1'b0;
@@ -513,6 +533,7 @@ module controller #(parameter MDIO_ADDR_SZ = 7, parameter NUM_PHYS=3)
case (msg_addr[15:8])
MSG_MAC_ADDR[15:8]: mac_sel <= 1'b1;
MSG_PKT_FILTER_ADDR[15:8]: pkt_filter_sel <= 1'b1;
+ MSG_MLE_ADDR[15:8]: mle_sel <= 1'b1;
endcase
end
end
@@ -520,6 +541,9 @@ module controller #(parameter MDIO_ADDR_SZ = 7, parameter NUM_PHYS=3)
hf_tx_sel <= 1'b0;
hf_rx_sel <= 1'b0;
mem_we <= 1'b0;
+ mac_sel <= 1'b0;
+ mle_sel <= 1'b0;
+ pkt_filter_sel <= 1'b0;
end
else if (mem_state == MEM_ST_REPLY_START && tx_fifo_empty) begin // write byte cnt
hf_ptrs_sel <= 1'b1;
@@ -579,8 +603,6 @@ module controller #(parameter MDIO_ADDR_SZ = 7, parameter NUM_PHYS=3)
mem_we <= 1'b0;
mem_d_o <= 32'd0;
mem_addr <= HF_NULL;
- mac_sel <= 1'b0;
- pkt_filter_sel <= 1'b0;
hf_ptrs_sel <= 1'b0;
hf_tx_sel <= 1'b0;
hf_rx_sel <= 1'b0;
@@ -606,11 +628,9 @@ module controller #(parameter MDIO_ADDR_SZ = 7, parameter NUM_PHYS=3)
always @(posedge clk, negedge rstn)
if (!rstn)
- tx_pkt_cnt <= 16'd0;
+ tx_msg_cnt <= 16'd0;
else if (mem_state == MEM_ST_DONE) // MSG
- tx_pkt_cnt <= tx_pkt_cnt + 1'b1;
-
-
+ tx_msg_cnt <= tx_msg_cnt + 1'b1;
/***********************************************************************
*

Highly Recommended Verilog Books