summaryrefslogtreecommitdiffhomepage
path: root/src/ml_engine.v
diff options
context:
space:
mode:
Diffstat (limited to 'src/ml_engine.v')
-rw-r--r--src/ml_engine.v107
1 files changed, 89 insertions, 18 deletions
diff --git a/src/ml_engine.v b/src/ml_engine.v
index ec50d87..9bde7fe 100644
--- a/src/ml_engine.v
+++ b/src/ml_engine.v
@@ -1,7 +1,7 @@
/*
- * ml_engine.v
+ * ml_engine.v
*
- * Copyright (C) 2025 Private Island Networks Inc.
+ * Copyright (C) 2025, 2026 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.
@@ -56,7 +56,11 @@ module ml_engine #(parameter NUM_IF=8, DPRAM_DEPTH=1024)
);
-`define DIRECT_OUTPUT // this disables processing and second DPRAM
+`define INCLUDED
+`include "mle_params.v"
+`undef INCLUDED
+
+`define DIRECT_OUTPUT // this disables internal processing and second DPRAM
localparam BLOCK_OFFSET = 'h80; // 128 bytes
localparam BLOCK_OFFSET_SHIT = 'd7; // Left shift to multiple by 128
@@ -71,8 +75,8 @@ module ml_engine #(parameter NUM_IF=8, DPRAM_DEPTH=1024)
localparam EVT_CNT_DELAY_1 = 32'h0000_0010,
EVT_CNT_DELAY_2 = 32'h0000_0020,
EVT_CNT_OUT = 32'h0000_0030,
- EVT_CNT_STOP = 32'h0800_0000,
- EVT_CNT_MAX = 32'h1000_0000; // Sets max event interval
+ EVT_CNT_STOP = 32'h0010_0000,
+ EVT_CNT_MAX = 32'h0040_0000; // Sets max event interval
`endif
@@ -83,6 +87,11 @@ module ml_engine #(parameter NUM_IF=8, DPRAM_DEPTH=1024)
localparam MLE_ST_IDLE=4'h0, MLE_ST_START=4'h1, MLE_ST_EVT_START = 4'h2,
MLE_ST_DU_START = 4'h3, MLE_ST_DU_CONT = 4'h4, MLE_ST_DU_DONE = 4'h5,
MLE_ST_EVT_DONE = 4'h6;
+
+
+ // FSM_3 States: header followed by data
+ localparam MLE_3_ST_IDLE=4'h0, MLE_3_ST_HDR = 4'h1, MLE_3_ST_DATA = 4'h2,
+ MLE_3_ST_PAD = 4'h3, MLE_3_ST_EVT_DONE = 4'h4;
// variables
reg mle_enable, mle_enable_m1, mle_enable_m2;
@@ -90,8 +99,12 @@ module ml_engine #(parameter NUM_IF=8, DPRAM_DEPTH=1024)
reg evt_delay_1, evt_delay_2, evt_delay_out;
reg [NUM_IF-1:0] empty_m1, empty_m2;
+
+ reg [3:0] mle_0_state, mle_1_state, mle_2_state, mle_3_state;
+ reg [2:0] mle_3_hdr_cnt;
+ reg [7:0] mle_3_hdr, mle_3_token;
- // Set up 1K DPRAM as 8 blocks of 128 words.
+ // Set up (default) 1K DPRAM as 8 blocks of 128 words.
wire [$clog2(DPRAM_DEPTH)-1:0] wr_addr0, wr_addr1;
wire [$clog2(DPRAM_DEPTH)-1:0] rd_addr0, rd_addr1;
reg [2:0] wr_block0, wr_block1;
@@ -108,7 +121,7 @@ module ml_engine #(parameter NUM_IF=8, DPRAM_DEPTH=1024)
wire we0, we1;
- reg [3:0] mle_0_state, mle_1_state, mle_2_state;
+
reg d_out_avail;
wire [8:0] fifo_d;
reg fifo_empty;
@@ -116,6 +129,7 @@ module ml_engine #(parameter NUM_IF=8, DPRAM_DEPTH=1024)
// Debug
reg [8*12:1] mle_0_state_str;
+ reg [8*12:1] mle_3_state_str;
/******************************************************
@@ -323,8 +337,8 @@ module ml_engine #(parameter NUM_IF=8, DPRAM_DEPTH=1024)
`ifdef DIRECT_OUTPUT
assign rd_oe0 = fifo_re;
- assign fifo_d = d_s0_o;
- assign fifo_d_o[7:0] = fifo_empty ? 8'h00 : d_s0_o[7:0];
+ assign fifo_d = (mle_3_state == MLE_3_ST_HDR) ? mle_3_hdr : d_s0_o;
+ assign fifo_d_o[7:0] = fifo_empty ? 8'h00 : fifo_d[7:0];
assign fifo_d_o[8] = fifo_empty_o ? 1'b1 : 1'b0;
assign rd_addr0 = rd_addr1;
assign wr_addr1 = wr_addr0;
@@ -472,16 +486,14 @@ module ml_engine #(parameter NUM_IF=8, DPRAM_DEPTH=1024)
mle_2_state <= MLE_ST_IDLE;
default: mle_2_state <= mle_2_state;
endcase
-
-
- /******************************************************
-
- Output, Switch reads from dpram_s1
-
- ******************************************************/
-
`endif
+
+ /******************************************************
+
+ Output, Switch reads from dpram_s1
+
+ ******************************************************/
// d_out_avail: data for output is available
always @(posedge clk, negedge rstn)
@@ -501,6 +513,65 @@ module ml_engine #(parameter NUM_IF=8, DPRAM_DEPTH=1024)
else
evt_delay_out <= 1'b0;
+
+ /******************************************************
+
+ FSM_3, Provide output data (header + DPRAM)
+
+ ******************************************************/
+
+ // FSM_3:
+ always @(posedge clk, negedge rstn)
+ if (!rstn)
+ mle_3_state <= MLE_3_ST_IDLE;
+ else
+ case (mle_3_state)
+ MLE_3_ST_IDLE: if (evt_delay_out)
+ mle_3_state <= MLE_3_ST_HDR;
+ MLE_3_ST_HDR: if (mle_3_hdr_cnt == SZ_MLE_HEADER)
+ mle_3_state <= MLE_3_ST_DATA;
+ MLE_3_ST_DATA: if (fifo_d_out_flag)
+ mle_3_state <= MLE_3_ST_PAD;
+ MLE_3_ST_PAD: if (fifo_empty_o)
+ mle_3_state <= MLE_3_ST_EVT_DONE;
+ MLE_3_ST_EVT_DONE:
+ mle_3_state <= MLE_3_ST_IDLE;
+ default: mle_3_state <= mle_3_state;
+ endcase
+
+ always @(*)
+ case(mle_3_state)
+ MLE_3_ST_IDLE: mle_3_state_str <= "IDLE";
+ MLE_3_ST_HDR: mle_3_state_str <= "HDR";
+ MLE_3_ST_DATA: mle_3_state_str <= "DATA";
+ MLE_3_ST_PAD: mle_3_state_str <= "PAD";
+ MLE_3_ST_EVT_DONE: mle_3_state_str <= "EVT_DONE";
+ default: mle_3_state_str <= "UNDEFINED";
+ endcase
+
+ // mle_3_hdr_cnt
+ always @(posedge clk, negedge rstn)
+ if (!rstn)
+ mle_3_hdr_cnt <= 3'd0;
+ else if (mle_3_state == MLE_3_ST_EVT_DONE)
+ mle_3_hdr_cnt <= 3'd0;
+ else if (fifo_re && mle_3_state == MLE_3_ST_HDR)
+ mle_3_hdr_cnt <= mle_3_hdr_cnt + 1'b1;
+
+ // mle_3_token
+ always @(posedge clk, negedge rstn)
+ if (!rstn)
+ mle_3_token <= 8'h00;
+ else if (mle_3_state == MLE_3_ST_EVT_DONE)
+ mle_3_token <= mle_3_token + 1'b1;
+
+ always @(*)
+ case(mle_3_hdr_cnt)
+ 3'd1: mle_3_hdr = MSG_TYPE_MLE;
+ 3'd2: mle_3_hdr = mle_3_token;
+ default: mle_3_hdr = 8'h55;
+ endcase
+
// fifo_d_out_flag: bit 8 from dpram_s1
always @(posedge clk, negedge rstn)
if (!rstn)
@@ -546,7 +617,7 @@ module ml_engine #(parameter NUM_IF=8, DPRAM_DEPTH=1024)
rd_ptr1 <= 'd0;
else if (evt_delay_out)
rd_ptr1 <= 'd0;
- else if (fifo_re)
+ else if (fifo_re && (mle_3_state == MLE_3_ST_HDR && mle_3_hdr_cnt == 3'd2) || mle_3_state > MLE_3_ST_HDR)
rd_ptr1 <= rd_ptr1 + 1'b1;
assign rd_addr1 = (rd_block1 << BLOCK_OFFSET_SHIT) + rd_ptr1;

Highly Recommended Verilog Books