From 0208c083ad875d0b68f748c97b9dc6b43139bf94 Mon Sep 17 00:00:00 2001 From: dwf1m12 <d.w.flynn@soton.ac.uk> Date: Tue, 28 Jan 2025 09:32:50 +0000 Subject: [PATCH] upgrade extio8x4 arbitration --- extio8x4-axis/rtl/extio8x4_ifsm.v | 76 +++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/extio8x4-axis/rtl/extio8x4_ifsm.v b/extio8x4-axis/rtl/extio8x4_ifsm.v index 073415c..d1a207a 100644 --- a/extio8x4-axis/rtl/extio8x4_ifsm.v +++ b/extio8x4-axis/rtl/extio8x4_ifsm.v @@ -43,8 +43,10 @@ module extio8x4_ifsm input wire ioack_s ); + // Fair priority sequencer // return next 12 transactions - to support 1,2,3 and 4 requests +//extio8x4_ifsm_arb_scramble_patch.v function [23:0] FNpriority_seq12x2; input [3:0] req4; case (req4[3:0]) @@ -63,7 +65,7 @@ case (req4[3:0]) 4'b1101: FNpriority_seq12x2 = 24'b11_10_00_11_10_00_11_10_00_11_10_00; // chan 0/2/3 4'b1110: FNpriority_seq12x2 = 24'b11_10_01_11_10_01_11_10_01_11_10_01; // chan 1/2/3 4'b1111: FNpriority_seq12x2 = 24'b11_10_01_00_11_10_01_00_11_10_01_00; // chan 0/1/2/3 -default: FNpriority_seq12x2 = 24'b0; // (no requests) +default: FNpriority_seq12x2 = 24'b00_00_00_00_00_00_00_00_00_00_00_00; // (no requests) endcase endfunction @@ -263,12 +265,76 @@ end wire [3:0] cmd4_nxt; +reg [4:0] hist_req0; +reg [4:0] hist_req1; +reg [4:0] hist_req2; +reg [4:0] hist_req3; + +wire [3:0] active_ack4; // one of 4 decode +assign active_ack4[0] = !cmd4_nxt[1] & !cmd4_nxt[0]; +assign active_ack4[1] = !cmd4_nxt[1] & cmd4_nxt[0]; +assign active_ack4[2] = cmd4_nxt[1] & !cmd4_nxt[0]; +assign active_ack4[3] = cmd4_nxt[1] & cmd4_nxt[0]; + +wire [3:0] pending_req; // active but not acknowledged +assign pending_req = active_req4 & ~active_ack4; + +// build binary weighted history of last 4 requests not yet granted +always @(posedge clk or negedge resetn) +begin + if (!resetn) begin + hist_req0 <= 5'b00000; // clear history + hist_req1 <= 5'b00000; + hist_req2 <= 5'b00000; + hist_req3 <= 5'b00000; + end + else if (start_xfer) begin + hist_req0 <= {pending_req[0],hist_req0[4:1]}; // req history + hist_req1 <= {pending_req[1],hist_req1[4:1]}; + hist_req2 <= {pending_req[2],hist_req2[4:1]}; + hist_req3 <= {pending_req[3],hist_req3[4:1]}; + cmd4 <= cmd4_nxt; + end +end + +// binary weighted pending request fraction (bits 3:0) +wire [3:0] pend_pri0 = (hist_req0[3:0]); +wire [3:0] pend_pri1 = (hist_req1[3:0]); +wire [3:0] pend_pri2 = (hist_req2[3:0]); +wire [3:0] pend_pri3 = (hist_req3[3:0]); + +wire [3:0] pri_vote; +// priority voting - ( > tests only win) +assign pri_vote[0] = (pend_pri0 > pend_pri1) + & (pend_pri0 > pend_pri2) + & (pend_pri0 > pend_pri3) + ; +assign pri_vote[1] = (pend_pri1 > pend_pri0) + & (pend_pri1 > pend_pri2) + & (pend_pri1 > pend_pri3) + ; +assign pri_vote[2] = (pend_pri2 > pend_pri0) + & (pend_pri2 > pend_pri1) + & (pend_pri2 > pend_pri3) + ; +assign pri_vote[3] = (pend_pri3 > pend_pri0) + & (pend_pri3 > pend_pri1) + & (pend_pri3 > pend_pri2) + ; + +wire [3:0] pri_req; +assign pri_req = active_req4 & pri_vote; // priority from history + +// in case of dead heats, or Zero, modify priority +wire [3:0] pri_mod; +assign pri_mod = (|pri_req) ? pri_req : active_req4; // if no history + // command resister always @(posedge clk or negedge resetn) begin if (!resetn) cmd4 <= 4'b0000; // invalid xfer pattern - else if (cmd4_req) + else if (start_xfer) cmd4 <= cmd4_nxt; end @@ -278,10 +344,12 @@ end assign cmd4_nxt[0] = (vrx0_req | vrx1_req); // Read/not-write always has priority assign cmd4_nxt[1] = !(vrx0_req | vtx0_req); */ -assign cmd4_nxt[1:0] = FNmap_patt2code2(FNpriority_seq12x2(active_req4), seq_cnt12); + +assign cmd4_nxt[1:0] = FNmap_patt2code2(FNpriority_seq12x2(pri_mod[3:0]), seq_cnt12); + /* */ -assign cmd4_nxt[3:2] = 2'b00; // fixed 8-bit transfer +assign cmd4_nxt[3:2] = 2'b00; // fixed 8-bit transfer supported only // write data resister - for the committed channel reg [7:0] wdata8; -- GitLab