-
Notifications
You must be signed in to change notification settings - Fork 249
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] MultiThreshold by Binary Search #687
Changes from 35 commits
3002e62
3c92c2f
09c6da9
1dde247
95082d3
72832be
0d4e3be
28568c6
280870d
2bf1a21
4c7b5ac
7663d3f
55e2eac
fa5d71a
174c0ff
2ec20e5
8616148
275abad
8849c02
84704ed
9aa7ff3
608b5da
ca6e7e7
7266ee9
f88bdbf
560771a
e763bf8
84e08f1
b0be07a
30d22f8
3594edd
0bee70d
0689c6a
e9a4a7b
41c0b4b
71ef39b
47a0cf9
bdd100f
d44a66c
f79b9ec
7b82de2
e2816d3
61acc64
bda05ae
7388e76
e965396
2b8a674
45bb19f
ca00422
7f3455f
4bc69f1
3b6a198
b3800cd
11464d8
e71b1c0
3be1140
e05effc
48c3304
1e8a36c
08f1b5f
481d773
a51bef4
2c313ad
49bdd28
e663030
42dbf23
933d747
5c6dcd9
51acd11
9dd4e67
412de82
b886a5a
2c3de2a
7c9f5d8
3a0d59d
757e3a1
479575b
0d99b6c
5a77a32
eeed070
c270868
af22177
fab120b
5d6c964
bdfa6cb
6809351
4515cf7
b51498e
ff3b201
e0e263b
fc7e00d
f530aba
3cd600c
54afa63
29f9e1c
2c4c8e2
5d07a43
33fadc7
fcf579c
6c9d1f5
b247ffb
7be5ce4
a0120f2
81cad6e
c7c18d9
28e5ad7
bd7ec27
bc5b738
730bcf8
95d6a3e
8003c91
d9db257
073844a
98184ac
528184d
8fb250c
9de06be
038a58a
f39187c
7284d2c
aa57255
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
/****************************************************************************** | ||
* Copyright (C) 2022, Advanced Micro Devices, Inc. | ||
* All rights reserved. | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions are met: | ||
* | ||
* 1. Redistributions of source code must retain the above copyright notice, | ||
* this list of conditions and the following disclaimer. | ||
* | ||
* 2. Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* | ||
* 3. Neither the name of the copyright holder nor the names of its | ||
* contributors may be used to endorse or promote products derived from | ||
* this software without specific prior written permission. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | ||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||
* OR BUSINESS INTERRUPTION). HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
* | ||
* @brief Pipelined thresholding by binary search. | ||
* @author Thomas B. Preußer <[email protected]> | ||
* | ||
* @description | ||
* Produces the N-bit count of those among 2^N-1 thresholds that are not | ||
* larger than the corresponding input: | ||
* y = Σ(T_i <= x) | ||
* The result is computed by binary search. The runtime-configurable | ||
* thresholds must be written in ascending order: | ||
* i < j => T_i < T_j | ||
* The design supports channel folding allowing each input to be processed | ||
* with respect to a selectable set of thresholds. The corresponding | ||
* threshold configuration relies on a channel address prefix. Inputs are | ||
* accompanied by a channel selector. | ||
*****************************************************************************/ | ||
module $MODULE_NAME$ #( | ||
int unsigned N, // output precision | ||
int unsigned M, // input/threshold precision | ||
int unsigned C, // number of channels | ||
|
||
int BIAS, // offsetting the output [0, 2^N-1) -> [-BIAS, 2^N-1 - BIAS) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @preusser is the comment here correct? L154 reads so to me it appears the comment here should read
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good catch! @fionnodonohoe-xlnx, please, copy this change in the comment associated with the parameter. |
||
|
||
int unsigned C_BITS, | ||
int unsigned O_BITS | ||
)( | ||
// Global Control | ||
input logic clk, | ||
input logic rst, | ||
|
||
// Threshold Configuration | ||
input logic twe, | ||
input logic [$clog2(C)+N-1:0] twa, | ||
input logic [ M-1:0] twd, | ||
|
||
// Clock Enable for Stream Processing | ||
input logic en, | ||
|
||
// Input Stream | ||
input logic ivld, | ||
input logic [C_BITS-1:0] icnl, // Ignored for C == 1 | ||
input logic $SIGN$ [M -1:0] idat, | ||
|
||
// Output Stream | ||
output logic ovld, | ||
output logic [C_BITS-1:0] ocnl, | ||
output logic [O_BITS-1:0] odat | ||
); | ||
|
||
// Pipeline Links & Feed | ||
typedef struct packed { | ||
logic vld; // Valid data identification | ||
logic [C_BITS-1:0] cnl; // Channel | ||
logic $SIGN$ [M -1:0] val; // Original input value | ||
logic [0:N-1] res; // Assembling result with valid prefix [0:stage] after stage #stage | ||
} pipe_t; | ||
uwire pipe_t pipe[0:N]; | ||
assign pipe[0] = pipe_t'{ vld: ivld, cnl: icnl, val: idat, res: {N{1'bx}} }; // Feed original input | ||
|
||
// Stages: 0, 1, ..., N-1 | ||
uwire [0:N-1] tws = (twa[N-1:0]+1) & ~twa[N-1:0]; // Write Select per stage by address suffix | ||
for(genvar stage = 0; stage < N; stage++) begin : genStages | ||
|
||
// Threshold Memory | ||
uwire $SIGN$ [M-1:0] thresh; | ||
if(1) begin : blkUpdate | ||
|
||
// Write control: local select from global address | ||
uwire we = twe && tws[stage]; | ||
if((C == 1) && (stage == 0)) begin | ||
logic $SIGN$ [M-1:0] Thresh = 'x; | ||
always_ff @(posedge clk) begin | ||
if(rst) Thresh <= 'x; | ||
else if(we) Thresh <= twd; | ||
end | ||
assign thresh = Thresh; | ||
end | ||
else begin | ||
logic $SIGN$ [M-1:0] Threshs[C * 2**stage]; | ||
uwire [$clog2(C)+stage-1:0] wa = twa[$left(twa):N-stage]; | ||
uwire [$clog2(C)+stage-1:0] ra; | ||
if(C > 1) assign ra[stage+:C_BITS] = pipe[stage].cnl; | ||
if(stage) assign ra[stage-1:0] = pipe[stage].res[0:stage-1]; | ||
|
||
// Write | ||
always_ff @(posedge clk) begin | ||
if(we) Threshs[wa] <= twd; | ||
end | ||
|
||
// Read | ||
logic $SIGN$ [M-1:0] RdReg; | ||
always_ff @(posedge clk) begin | ||
if(en) RdReg <= Threshs[ra]; | ||
end | ||
assign thresh = RdReg; | ||
end | ||
|
||
end : blkUpdate | ||
|
||
// Pipeline regs simply copying the input | ||
pipe_t State = '{ vld: 0, cnl: 'x, val: 'x, res: 'x }; | ||
always_ff @(posedge clk) begin | ||
if(rst) State <= '{ vld: 0, cnl: 'x, val: 'x, res: 'x }; | ||
else if(en) State <= pipe[stage]; | ||
end | ||
|
||
// Assemble pipeline data | ||
logic [0:N-1] res; | ||
always_comb begin | ||
res = State.res; | ||
res[stage] = thresh <= State.val; // Patch in next result bit | ||
end | ||
assign pipe[stage+1] = '{ | ||
vld: State.vld, | ||
cnl: State.cnl, | ||
val: State.val, | ||
res: res | ||
}; | ||
|
||
end : genStages | ||
|
||
// Output | ||
assign ovld = pipe[N].vld; | ||
assign ocnl = pipe[N].cnl; | ||
assign odat = pipe[N].res + BIAS; | ||
|
||
endmodule : $MODULE_NAME$ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
/****************************************************************************** | ||
* Copyright (C) 2022, Advanced Micro Devices, Inc. | ||
* All rights reserved. | ||
* | ||
* Redistribution and use in source and binary forms, with or without | ||
* modification, are permitted provided that the following conditions are met: | ||
* | ||
* 1. Redistributions of source code must retain the above copyright notice, | ||
* this list of conditions and the following disclaimer. | ||
* | ||
* 2. Redistributions in binary form must reproduce the above copyright | ||
* notice, this list of conditions and the following disclaimer in the | ||
* documentation and/or other materials provided with the distribution. | ||
* | ||
* 3. Neither the name of the copyright holder nor the names of its | ||
* contributors may be used to endorse or promote products derived from | ||
* this software without specific prior written permission. | ||
* | ||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, | ||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR | ||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; | ||
* OR BUSINESS INTERRUPTION). HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, | ||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR | ||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | ||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
* | ||
* @brief All-AXI interface adapter for thresholding module. | ||
* @author Thomas B. Preußer <[email protected]> | ||
*****************************************************************************/ | ||
|
||
module $MODULE_NAME_AXI$ #( | ||
int unsigned N, // output precision | ||
int unsigned M, // input/threshold precision | ||
int unsigned C, // Channels | ||
|
||
int BIAS, // offsetting the output [0, 2^N-1) -> [-BIAS, 2^N-1 - BIAS) | ||
|
||
int unsigned O_BITS | ||
)( | ||
//- Global Control ------------------ | ||
input logic ap_clk, | ||
input logic ap_rst_n, | ||
|
||
//- AXI Lite ------------------------ | ||
// Writing | ||
input logic s_axilite_AWVALID, | ||
output logic s_axilite_AWREADY, | ||
input logic [$clog2(C)+N-1:0] s_axilite_AWADDR, | ||
|
||
input logic s_axilite_WVALID, | ||
output logic s_axilite_WREADY, | ||
input logic [31:0] s_axilite_WDATA, | ||
input logic [ 3:0] s_axilite_WSTRB, | ||
|
||
output logic s_axilite_BVALID, | ||
input logic s_axilite_BREADY, | ||
output logic [1:0] s_axilite_BRESP, | ||
|
||
// Reading | ||
input logic s_axilite_ARVALID, | ||
output logic s_axilite_ARREADY, | ||
input logic [0:0] s_axilite_ARADDR, | ||
|
||
output logic s_axilite_RVALID, | ||
input logic s_axilite_RREADY, | ||
output logic [31:0] s_axilite_RDATA, | ||
output logic [ 1:0] s_axilite_RRESP, | ||
|
||
//- AXI Stream - Input -------------- | ||
output logic s_axis_tready, | ||
input logic s_axis_tvalid, | ||
input logic [((M+7)/8)*8-1:0] s_axis_tdata, | ||
|
||
//- AXI Stream - Output ------------- | ||
input logic m_axis_tready, | ||
output logic m_axis_tvalid, | ||
output logic [((O_BITS+7)/8)*8-1:0] m_axis_tdata | ||
); | ||
//- Global Control ------------------------------------------------------ | ||
uwire clk = ap_clk; | ||
uwire rst = !ap_rst_n; | ||
|
||
//- AXI Lite: Threshold Configuration ----------------------------------- | ||
uwire twe; | ||
uwire [$clog2(C)+N-1:0] twa; | ||
uwire [ M-1:0] twd; | ||
if(1) begin : blkAxiLite | ||
logic WABusy = 0; | ||
logic WDBusy = 0; | ||
logic [$clog2(C)+N-1:0] Addr = 'x; | ||
logic [ M-1:0] Data = 'x; | ||
|
||
assign twe = WABusy && WDBusy; | ||
assign twa = Addr; | ||
assign twd = Data; | ||
|
||
uwire clr_wr = rst || (twe && s_axilite_BREADY); | ||
always_ff @(posedge clk) begin : blockName | ||
if(clr_wr) begin | ||
WABusy <= 0; | ||
Addr <= 'x; | ||
WDBusy <= 0; | ||
Data <= 'x; | ||
end | ||
else begin | ||
if(!WABusy) begin | ||
WABusy <= s_axilite_AWVALID; | ||
Addr <= s_axilite_AWADDR[$clog2(C)+N-1:0]; | ||
end | ||
if(!WDBusy) begin | ||
WDBusy <= s_axilite_WVALID; | ||
Data <= s_axilite_WDATA[M-1:0]; | ||
end | ||
end | ||
end | ||
assign s_axilite_AWREADY = !WABusy; | ||
assign s_axilite_WREADY = !WDBusy; | ||
assign s_axilite_BVALID = WABusy && WDBusy; | ||
assign s_axilite_BRESP = '0; // OK | ||
|
||
// Answer all reads with '1 | ||
logic RValid = 0; | ||
uwire clr_rd = rst || (RValid && s_axilite_RREADY); | ||
always_ff @(posedge clk) begin | ||
if(clr_rd) RValid <= 0; | ||
else if(!RValid) RValid <= s_axilite_ARVALID; | ||
end | ||
assign s_axilite_ARREADY = !RValid; | ||
assign s_axilite_RVALID = RValid; | ||
assign s_axilite_RDATA = '1; | ||
assign s_axilite_RRESP = '0; // OK | ||
|
||
end : blkAxiLite | ||
|
||
//- IO-Sandwich with two-stage output buffer for containing a local enable | ||
uwire en; | ||
uwire [O_BITS-1:0] odat; | ||
uwire ovld; | ||
if(1) begin : blkOutputDecouple | ||
typedef struct { | ||
logic vld; | ||
logic [O_BITS-1:0] dat; | ||
} buf_t; | ||
buf_t Buf[2] = '{ default: '{ vld: 0, dat: 'x } }; | ||
always_ff @(posedge clk) begin | ||
if(rst) Buf <= '{ default: '{ vld: 0, dat: 'x } }; | ||
else begin | ||
if(!Buf[1].vld || m_axis_tready) begin | ||
Buf[1] <= '{ | ||
vld: Buf[0].vld || ovld, | ||
dat: Buf[0].vld? Buf[0].dat : odat | ||
}; | ||
end | ||
Buf[0].vld <= Buf[1].vld && !m_axis_tready && (Buf[0].vld || ovld); | ||
if(!Buf[0].vld) Buf[0].dat <= odat; | ||
end | ||
end | ||
assign en = !Buf[0].vld; | ||
|
||
assign m_axis_tvalid = Buf[1].vld; | ||
assign m_axis_tdata = Buf[1].dat; | ||
|
||
end : blkOutputDecouple | ||
|
||
localparam int unsigned C_BITS = C < 2? 1 : $clog2(C); | ||
uwire ivld = s_axis_tvalid; | ||
uwire [C_BITS-1:0] icnl; | ||
uwire [M -1:0] idat = s_axis_tdata[M-1:0]; | ||
assign s_axis_tready = en; | ||
if(C == 1) assign icnl = 'x; | ||
else begin | ||
logic [C_BITS-1:0] Chnl = 0; | ||
logic Last = 0; | ||
uwire inc = ivld && en; | ||
uwire clr = rst || (Last && inc); | ||
always_ff @(posedge clk) begin | ||
if(clr) begin | ||
Chnl <= 0; | ||
Last <= 0; | ||
end | ||
else if(inc) begin | ||
Chnl <= Chnl + 1; | ||
Last <= (~Chnl & (C-2)) == 0; | ||
end | ||
end | ||
assign icnl = Chnl; | ||
end | ||
|
||
// Core Thresholding Module | ||
$MODULE_NAME$ #(.N(N), .M(M), .C(C), .BIAS(BIAS), .O_BITS(O_BITS), .C_BITS(C_BITS)) core ( | ||
.clk, .rst, | ||
.twe, .twa, .twd, | ||
.en, | ||
.ivld, .icnl, .idat, | ||
.ovld, .ocnl(), .odat | ||
); | ||
|
||
endmodule : $MODULE_NAME_AXI$ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@preusser for clarity, is this the variant that supports FP32 thresholding? or is this for integers only?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the base version for integers only at this point.