mirror of
https://github.com/pConst/basic_verilog.git
synced 2025-01-14 06:42:54 +08:00
Added altera cookbook
This commit is contained in:
parent
25b74793e0
commit
40533743d7
45
Advanced Synthesis Cookbook/arbitration/arbiter.v
Normal file
45
Advanced Synthesis Cookbook/arbitration/arbiter.v
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// baeckler - 02-13-2007
|
||||
//
|
||||
// 'base' is a one hot signal indicating the first request
|
||||
// that should be considered for a grant. Followed by higher
|
||||
// indexed requests, then wrapping around.
|
||||
//
|
||||
|
||||
module arbiter (
|
||||
req, grant, base
|
||||
);
|
||||
|
||||
parameter WIDTH = 16;
|
||||
|
||||
input [WIDTH-1:0] req;
|
||||
output [WIDTH-1:0] grant;
|
||||
input [WIDTH-1:0] base;
|
||||
|
||||
wire [2*WIDTH-1:0] double_req = {req,req};
|
||||
wire [2*WIDTH-1:0] double_grant = double_req & ~(double_req-base);
|
||||
assign grant = double_grant[WIDTH-1:0] | double_grant[2*WIDTH-1:WIDTH];
|
||||
|
||||
endmodule
|
99
Advanced Synthesis Cookbook/arbitration/arbiter_tb.v
Normal file
99
Advanced Synthesis Cookbook/arbitration/arbiter_tb.v
Normal file
@ -0,0 +1,99 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//baeckler - 02-13-2007
|
||||
|
||||
module arbiter_tb ();
|
||||
|
||||
reg [15:0] req;
|
||||
reg [3:0] base;
|
||||
|
||||
wire [15:0] grant, grant_two;
|
||||
reg fail;
|
||||
|
||||
// weaker unit for testing
|
||||
reference_arbiter arb (.req(req),.base(base),.grant(grant));
|
||||
|
||||
// convert the encoded base to one hot
|
||||
// ideally it would be generated in one hot
|
||||
reg [15:0] decoded_base;
|
||||
always @(*) begin
|
||||
decoded_base = 0;
|
||||
decoded_base[base] = 1'b1;
|
||||
end
|
||||
|
||||
// device under test
|
||||
arbiter a2 (.req(req),.grant(grant_two),.base(decoded_base));
|
||||
defparam a2 .WIDTH = 16;
|
||||
|
||||
always begin
|
||||
#100
|
||||
req = $random & $random & $random;
|
||||
base = $random;
|
||||
|
||||
#5
|
||||
if (grant !== grant_two) begin
|
||||
$display ("Mismatch at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
end
|
||||
|
||||
initial begin
|
||||
fail = 0;
|
||||
#1000000 if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Less efficient easier to understand
|
||||
// unit for reference
|
||||
/////////////////////////////////////////
|
||||
module reference_arbiter (
|
||||
req,grant,base
|
||||
);
|
||||
|
||||
input [15:0] req;
|
||||
output [15:0] grant;
|
||||
input [3:0] base;
|
||||
|
||||
// rotate the request lines
|
||||
wire [15:0] b0 = base[0] ? {req[0],req[15:1]} : req[15:0] ;
|
||||
wire [15:0] b1 = base[1] ? {b0[1:0],b0[15:2]} : b0[15:0] ;
|
||||
wire [15:0] b2 = base[2] ? {b1[3:0],b1[15:4]} : b1[15:0] ;
|
||||
wire [15:0] b3 = base[3] ? {b2[7:0],b2[15:8]} : b2[15:0] ;
|
||||
|
||||
// pick the lowest one for a grant
|
||||
wire [15:0] rotated_grant = b3 & ~(b3-1);
|
||||
|
||||
// unrotate the grant
|
||||
wire [15:0] b4 = base[0] ? {rotated_grant[14:0],rotated_grant[15]} : rotated_grant[15:0] ;
|
||||
wire [15:0] b5 = base[1] ? {b4[13:0],b4[15:14]} : b4[15:0] ;
|
||||
wire [15:0] b6 = base[2] ? {b5[11:0],b5[15:12]} : b5[15:0] ;
|
||||
wire [15:0] b7 = base[3] ? {b6[7:0],b6[15:8]} : b6[15:0] ;
|
||||
|
||||
assign grant = b7;
|
||||
|
||||
endmodule
|
31
Advanced Synthesis Cookbook/arbitration/bitscan.v
Normal file
31
Advanced Synthesis Cookbook/arbitration/bitscan.v
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module bitscan (req,sel);
|
||||
parameter WIDTH = 16;
|
||||
input [WIDTH-1:0] req;
|
||||
output [WIDTH-1:0] sel;
|
||||
|
||||
assign sel = req & ~(req-1);
|
||||
|
||||
endmodule
|
||||
|
63
Advanced Synthesis Cookbook/arbitration/bitscan_tb.v
Normal file
63
Advanced Synthesis Cookbook/arbitration/bitscan_tb.v
Normal file
@ -0,0 +1,63 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module bitscan_tb ();
|
||||
parameter WIDTH = 16;
|
||||
reg [WIDTH-1:0] req;
|
||||
wire [WIDTH-1:0] sel;
|
||||
|
||||
bitscan b (.req(req),.sel(sel));
|
||||
defparam b .WIDTH = WIDTH;
|
||||
|
||||
initial begin
|
||||
req = 16'h8000;
|
||||
end
|
||||
|
||||
integer n;
|
||||
reg [WIDTH-1:0] result;
|
||||
reg fail = 0;
|
||||
|
||||
always begin
|
||||
#100 req = $random & $random & $random;
|
||||
#10
|
||||
result = 0;
|
||||
for (n=0; n<WIDTH; n=n+1)
|
||||
begin
|
||||
if (req[n] == 1'b1) begin
|
||||
result[n] = 1'b1;
|
||||
n = WIDTH;
|
||||
end
|
||||
end
|
||||
#10 if (sel !== result) begin
|
||||
$display ("Mismatch at time %d",$time);
|
||||
fail = 1'b1;
|
||||
$stop();
|
||||
end
|
||||
end
|
||||
|
||||
initial begin
|
||||
#1000000 if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
endmodule
|
41
Advanced Synthesis Cookbook/arbitration/log2.inc
Normal file
41
Advanced Synthesis Cookbook/arbitration/log2.inc
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 12-12-2006
|
||||
// helper function to compute LOG base 2
|
||||
//
|
||||
// NOTE - This is a somewhat abusive definition of LOG2(v) as the
|
||||
// number of bits required to represent "v". So log2(256) will be
|
||||
// 9 rather than 8 (256 = 9'b1_0000_0000). I apologize for any
|
||||
// confusion this may cause.
|
||||
//
|
||||
|
||||
function integer log2;
|
||||
input integer val;
|
||||
begin
|
||||
log2 = 0;
|
||||
while (val > 0) begin
|
||||
val = val >> 1;
|
||||
log2 = log2 + 1;
|
||||
end
|
||||
end
|
||||
endfunction
|
78
Advanced Synthesis Cookbook/arbitration/prio_encode.cpp
Normal file
78
Advanced Synthesis Cookbook/arbitration/prio_encode.cpp
Normal file
@ -0,0 +1,78 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//baeckler - 11-14-2006
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int log2 (int n)
|
||||
{
|
||||
int bits = 0;
|
||||
while (n)
|
||||
{
|
||||
n >>= 1;
|
||||
bits++;
|
||||
}
|
||||
return (bits);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
unsigned int num_ins = 6;
|
||||
unsigned int num_outs = log2(num_ins);
|
||||
|
||||
unsigned int num_cases = (1<<num_ins);
|
||||
unsigned int n = 0, k = 0;
|
||||
unsigned int out_val = 0;
|
||||
|
||||
fprintf (stdout,"//baeckler - 11-14-2006\n");
|
||||
fprintf (stdout,"// priority encoder\n");
|
||||
fprintf (stdout,"// no requests - output = 0\n");
|
||||
fprintf (stdout,"// request bit 0 (highest priority) - output = 1\n");
|
||||
fprintf (stdout,"// request bit %d (lowest priority) - output = %d\n",num_ins-1,num_ins);
|
||||
fprintf (stdout,"module prio_encode (reqs,out);\n");
|
||||
fprintf (stdout,"input [%d:0] reqs;\n",num_ins-1);
|
||||
fprintf (stdout,"output [%d:0] out;\n",num_outs-1);
|
||||
fprintf (stdout,"reg [%d:0] out;\n\n",num_outs-1);
|
||||
|
||||
fprintf (stdout," always @(*) begin\n");
|
||||
fprintf (stdout," case(reqs)\n");
|
||||
|
||||
fprintf (stdout," // 0 is special, no reqs\n");
|
||||
fprintf (stdout," %d'd%d: out = %d;\n\n",num_ins,0,0);
|
||||
|
||||
for (n=1; n<num_cases; n++)
|
||||
{
|
||||
out_val = 1;
|
||||
k = n;
|
||||
while (k && !(k&1))
|
||||
{
|
||||
k >>=1;
|
||||
out_val += 1;
|
||||
}
|
||||
fprintf (stdout," %d'd%d: out = %d;\n",num_ins,n,out_val);
|
||||
}
|
||||
fprintf (stdout," endcase\n");
|
||||
fprintf (stdout," end\n");
|
||||
fprintf (stdout,"endmodule\n");
|
||||
return (0);
|
||||
}
|
103
Advanced Synthesis Cookbook/arbitration/prio_encode.v
Normal file
103
Advanced Synthesis Cookbook/arbitration/prio_encode.v
Normal file
@ -0,0 +1,103 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//baeckler - 11-14-2006
|
||||
// priority encoder
|
||||
// no requests - output = 0
|
||||
// request bit 0 (highest priority) - output = 1
|
||||
// request bit 5 (lowest priority) - output = 6
|
||||
module prio_encode (reqs,out);
|
||||
input [5:0] reqs;
|
||||
output [2:0] out;
|
||||
reg [2:0] out;
|
||||
|
||||
always @(*) begin
|
||||
case(reqs)
|
||||
// 0 is special, no reqs
|
||||
6'd0: out = 0;
|
||||
|
||||
6'd1: out = 1;
|
||||
6'd2: out = 2;
|
||||
6'd3: out = 1;
|
||||
6'd4: out = 3;
|
||||
6'd5: out = 1;
|
||||
6'd6: out = 2;
|
||||
6'd7: out = 1;
|
||||
6'd8: out = 4;
|
||||
6'd9: out = 1;
|
||||
6'd10: out = 2;
|
||||
6'd11: out = 1;
|
||||
6'd12: out = 3;
|
||||
6'd13: out = 1;
|
||||
6'd14: out = 2;
|
||||
6'd15: out = 1;
|
||||
6'd16: out = 5;
|
||||
6'd17: out = 1;
|
||||
6'd18: out = 2;
|
||||
6'd19: out = 1;
|
||||
6'd20: out = 3;
|
||||
6'd21: out = 1;
|
||||
6'd22: out = 2;
|
||||
6'd23: out = 1;
|
||||
6'd24: out = 4;
|
||||
6'd25: out = 1;
|
||||
6'd26: out = 2;
|
||||
6'd27: out = 1;
|
||||
6'd28: out = 3;
|
||||
6'd29: out = 1;
|
||||
6'd30: out = 2;
|
||||
6'd31: out = 1;
|
||||
6'd32: out = 6;
|
||||
6'd33: out = 1;
|
||||
6'd34: out = 2;
|
||||
6'd35: out = 1;
|
||||
6'd36: out = 3;
|
||||
6'd37: out = 1;
|
||||
6'd38: out = 2;
|
||||
6'd39: out = 1;
|
||||
6'd40: out = 4;
|
||||
6'd41: out = 1;
|
||||
6'd42: out = 2;
|
||||
6'd43: out = 1;
|
||||
6'd44: out = 3;
|
||||
6'd45: out = 1;
|
||||
6'd46: out = 2;
|
||||
6'd47: out = 1;
|
||||
6'd48: out = 5;
|
||||
6'd49: out = 1;
|
||||
6'd50: out = 2;
|
||||
6'd51: out = 1;
|
||||
6'd52: out = 3;
|
||||
6'd53: out = 1;
|
||||
6'd54: out = 2;
|
||||
6'd55: out = 1;
|
||||
6'd56: out = 4;
|
||||
6'd57: out = 1;
|
||||
6'd58: out = 2;
|
||||
6'd59: out = 1;
|
||||
6'd60: out = 3;
|
||||
6'd61: out = 1;
|
||||
6'd62: out = 2;
|
||||
6'd63: out = 1;
|
||||
endcase
|
||||
end
|
||||
endmodule
|
172
Advanced Synthesis Cookbook/arbitration/tx_4channel_arbiter.v
Normal file
172
Advanced Synthesis Cookbook/arbitration/tx_4channel_arbiter.v
Normal file
@ -0,0 +1,172 @@
|
||||
// Copyright 2008 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 10-03-2008
|
||||
|
||||
module tx_4channel_arbiter # (
|
||||
parameter NUM_DAT_WORDS = 8,
|
||||
parameter LOG_DAT_WORDS = 4, // enough bits to represent 0..#dat inclusive
|
||||
parameter CHANID0 = 8'h0,
|
||||
parameter CHANID1 = 8'h1,
|
||||
parameter CHANID2 = 8'h2,
|
||||
parameter CHANID3 = 8'h3
|
||||
)
|
||||
(
|
||||
input clk, arst,
|
||||
|
||||
// four input ports
|
||||
input [LOG_DAT_WORDS-1:0] num_chan0words_valid,
|
||||
input [64*NUM_DAT_WORDS-1:0] chan0words,
|
||||
input chan0sop,
|
||||
input [3:0] chan0eopbits,
|
||||
output chan0ready,
|
||||
input chan0valid,
|
||||
|
||||
input [LOG_DAT_WORDS-1:0] num_chan1words_valid,
|
||||
input [64*NUM_DAT_WORDS-1:0] chan1words,
|
||||
input chan1sop,
|
||||
input [3:0] chan1eopbits,
|
||||
output chan1ready,
|
||||
input chan1valid,
|
||||
|
||||
input [LOG_DAT_WORDS-1:0] num_chan2words_valid,
|
||||
input [64*NUM_DAT_WORDS-1:0] chan2words,
|
||||
input chan2sop,
|
||||
input [3:0] chan2eopbits,
|
||||
output chan2ready,
|
||||
input chan2valid,
|
||||
|
||||
input [LOG_DAT_WORDS-1:0] num_chan3words_valid,
|
||||
input [64*NUM_DAT_WORDS-1:0] chan3words,
|
||||
input chan3sop,
|
||||
input [3:0] chan3eopbits,
|
||||
output chan3ready,
|
||||
input chan3valid,
|
||||
|
||||
// output port
|
||||
output reg [LOG_DAT_WORDS-1:0] num_datwords_valid,
|
||||
output reg [64*NUM_DAT_WORDS-1:0] datwords,
|
||||
output reg [7:0] chan,
|
||||
output reg sop,
|
||||
output reg [3:0] eopbits,
|
||||
input ready,
|
||||
output valid
|
||||
);
|
||||
|
||||
localparam ARB_CHANS = 4;
|
||||
|
||||
reg [ARB_CHANS-1:0] qualified_req;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
qualified_req <= 0;
|
||||
end
|
||||
else begin
|
||||
qualified_req[0] <= chan0valid & (|num_chan0words_valid);
|
||||
qualified_req[1] <= chan1valid & (|num_chan1words_valid);
|
||||
qualified_req[2] <= chan2valid & (|num_chan2words_valid);
|
||||
qualified_req[3] <= chan3valid & (|num_chan3words_valid);
|
||||
end
|
||||
end
|
||||
|
||||
/////////////////////////////////////
|
||||
// arbiter with rotating fairness
|
||||
|
||||
reg [ARB_CHANS-1:0] base,grant;
|
||||
wire [ARB_CHANS-1:0] grant_w;
|
||||
reg [1:0] enc_grant;
|
||||
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
base <= 1;
|
||||
grant <= 0;
|
||||
enc_grant <= 0;
|
||||
end
|
||||
else begin
|
||||
if (ready) begin
|
||||
base <= {base[ARB_CHANS-2:0],base[ARB_CHANS-1]};
|
||||
grant <= grant_w;
|
||||
enc_grant <= {grant_w[3] | grant_w[2], grant_w[3] | grant_w[1]};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
arbiter arb (
|
||||
.req(qualified_req),
|
||||
.grant(grant_w),
|
||||
.base(base)
|
||||
);
|
||||
defparam arb .WIDTH = ARB_CHANS;
|
||||
|
||||
/////////////////////////////////////
|
||||
// ready the winner if any
|
||||
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
num_datwords_valid <= 0;
|
||||
datwords <= 0;
|
||||
chan <= 0;
|
||||
sop <= 0;
|
||||
eopbits <= 0;
|
||||
end
|
||||
else begin
|
||||
if (ready) begin
|
||||
if (enc_grant == 2'b00) begin
|
||||
num_datwords_valid <= num_chan0words_valid;
|
||||
datwords <= chan0words;
|
||||
sop <= chan0sop;
|
||||
eopbits <= chan0eopbits;
|
||||
chan <= CHANID0;
|
||||
end
|
||||
else if (enc_grant == 2'b01) begin
|
||||
num_datwords_valid <= num_chan1words_valid;
|
||||
datwords <= chan1words;
|
||||
sop <= chan1sop;
|
||||
eopbits <= chan1eopbits;
|
||||
chan <= CHANID1;
|
||||
end
|
||||
else if (enc_grant == 2'b10) begin
|
||||
num_datwords_valid <= num_chan2words_valid;
|
||||
datwords <= chan2words;
|
||||
sop <= chan2sop;
|
||||
eopbits <= chan2eopbits;
|
||||
chan <= CHANID2;
|
||||
end
|
||||
else begin
|
||||
num_datwords_valid <= num_chan3words_valid;
|
||||
datwords <= chan3words;
|
||||
sop <= chan3sop;
|
||||
eopbits <= chan3eopbits;
|
||||
chan <= CHANID3;
|
||||
end
|
||||
|
||||
if (~|grant) num_datwords_valid <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign chan0ready = grant[0] & ready;
|
||||
assign chan1ready = grant[1] & ready;
|
||||
assign chan2ready = grant[2] & ready;
|
||||
assign chan3ready = grant[3] & ready;
|
||||
assign valid = |num_datwords_valid;
|
||||
|
||||
endmodule
|
@ -0,0 +1,293 @@
|
||||
// Copyright 2009 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module tx_4channel_arbiter_tb ();
|
||||
|
||||
parameter NUM_DAT_WORDS = 2;
|
||||
parameter LOG_DAT_WORDS = 2;
|
||||
|
||||
reg clk, arst;
|
||||
|
||||
// four input ports
|
||||
reg [LOG_DAT_WORDS-1:0] num_chan0words_valid;
|
||||
reg [64*NUM_DAT_WORDS-1:0] chan0words;
|
||||
reg chan0sop;
|
||||
reg [3:0] chan0eopbits;
|
||||
wire chan0ready;
|
||||
reg chan0valid;
|
||||
|
||||
reg [LOG_DAT_WORDS-1:0] num_chan1words_valid;
|
||||
reg [64*NUM_DAT_WORDS-1:0] chan1words;
|
||||
reg chan1sop;
|
||||
reg [3:0] chan1eopbits;
|
||||
wire chan1ready;
|
||||
reg chan1valid;
|
||||
|
||||
reg [LOG_DAT_WORDS-1:0] num_chan2words_valid;
|
||||
reg [64*NUM_DAT_WORDS-1:0] chan2words;
|
||||
reg chan2sop;
|
||||
reg [3:0] chan2eopbits;
|
||||
wire chan2ready;
|
||||
reg chan2valid;
|
||||
|
||||
reg [LOG_DAT_WORDS-1:0] num_chan3words_valid;
|
||||
reg [64*NUM_DAT_WORDS-1:0] chan3words;
|
||||
reg chan3sop;
|
||||
reg [3:0] chan3eopbits;
|
||||
wire chan3ready;
|
||||
reg chan3valid;
|
||||
|
||||
// outport
|
||||
wire [LOG_DAT_WORDS-1:0] num_datwords_valid;
|
||||
wire [64*NUM_DAT_WORDS-1:0] datwords;
|
||||
wire [7:0] chan;
|
||||
wire sop;
|
||||
wire [3:0] eopbits;
|
||||
reg ready;
|
||||
wire valid;
|
||||
|
||||
tx_4channel_arbiter #
|
||||
(
|
||||
.NUM_DAT_WORDS(NUM_DAT_WORDS),
|
||||
.LOG_DAT_WORDS(LOG_DAT_WORDS)
|
||||
)
|
||||
dut
|
||||
(.*);
|
||||
|
||||
////////////////////////////////////////
|
||||
// Chan 0 driver
|
||||
////////////////////////////////////////
|
||||
reg chan0state;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
num_chan0words_valid <= 2'd2;
|
||||
chan0words <= 0;
|
||||
chan0sop <= 0;
|
||||
chan0eopbits <= 0;
|
||||
chan0valid <= 1'b1;
|
||||
chan0state <= 0;
|
||||
end
|
||||
else begin
|
||||
if (chan0ready) begin
|
||||
if (chan0state) begin
|
||||
num_chan0words_valid <= 2'd2;
|
||||
chan0words <= {"chan0abc","chan0def"};
|
||||
chan0sop <= 1'b1;
|
||||
chan0eopbits <= 0;
|
||||
end
|
||||
else begin
|
||||
num_chan0words_valid <= 2'd2;
|
||||
chan0words <= {"chan0ghi","chan0jki"};;
|
||||
chan0sop <= 0;
|
||||
chan0eopbits <= 4'b1000;
|
||||
end
|
||||
chan0state <= chan0state + 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
////////////////////////////////////////
|
||||
// Chan 1 driver
|
||||
////////////////////////////////////////
|
||||
reg chan1state;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
num_chan1words_valid <= 2'd2;
|
||||
chan1words <= 0;
|
||||
chan1sop <= 0;
|
||||
chan1eopbits <= 0;
|
||||
chan1valid <= 1'b1;
|
||||
chan1state <= 0;
|
||||
end
|
||||
else begin
|
||||
if (chan1ready) begin
|
||||
if (chan1state) begin
|
||||
num_chan1words_valid <= 2'd2;
|
||||
chan1words <= {"chan1abc","chan1def"};
|
||||
chan1sop <= 1'b1;
|
||||
chan1eopbits <= 0;
|
||||
end
|
||||
else begin
|
||||
num_chan1words_valid <= 2'd2;
|
||||
chan1words <= {"chan1ghi","chan1jki"};;
|
||||
chan1sop <= 0;
|
||||
chan1eopbits <= 4'b1000;
|
||||
end
|
||||
chan1state <= chan1state + 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
////////////////////////////////////////
|
||||
// Chan 2 driver
|
||||
////////////////////////////////////////
|
||||
reg chan2state;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
num_chan2words_valid <= 2'd2;
|
||||
chan2words <= 0;
|
||||
chan2sop <= 0;
|
||||
chan2eopbits <= 0;
|
||||
chan2valid <= 1'b1;
|
||||
chan2state <= 0;
|
||||
end
|
||||
else begin
|
||||
if (chan2ready) begin
|
||||
if (chan2state) begin
|
||||
num_chan2words_valid <= 2'd2;
|
||||
chan2words <= {"chan2abc","chan2def"};
|
||||
chan2sop <= 1'b1;
|
||||
chan2eopbits <= 0;
|
||||
end
|
||||
else begin
|
||||
num_chan2words_valid <= 2'd2;
|
||||
chan2words <= {"chan2ghi","chan2jki"};;
|
||||
chan2sop <= 0;
|
||||
chan2eopbits <= 4'b1000;
|
||||
end
|
||||
chan2state <= chan2state + 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
////////////////////////////////////////
|
||||
// Chan 3 driver
|
||||
////////////////////////////////////////
|
||||
reg chan3state;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
num_chan3words_valid <= 2'd2;
|
||||
chan3words <= 0;
|
||||
chan3sop <= 0;
|
||||
chan3eopbits <= 0;
|
||||
chan3valid <= 1'b1;
|
||||
chan3state <= 0;
|
||||
end
|
||||
else begin
|
||||
if (chan3ready) begin
|
||||
if (chan3state) begin
|
||||
num_chan3words_valid <= 2'd2;
|
||||
chan3words <= {"chan3abc","chan3def"};
|
||||
chan3sop <= 1'b1;
|
||||
chan3eopbits <= 0;
|
||||
end
|
||||
else begin
|
||||
num_chan3words_valid <= 2'd2;
|
||||
chan3words <= {"chan3ghi","chan3jki"};;
|
||||
chan3sop <= 0;
|
||||
chan3eopbits <= 4'b1000;
|
||||
end
|
||||
chan3state <= chan3state + 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
////////////////////////////////////////
|
||||
// simulate sink readiness and XON/XOFF
|
||||
////////////////////////////////////////
|
||||
reg all_off;
|
||||
always @(negedge clk) begin
|
||||
ready <= $random | $random;
|
||||
all_off <= $random & $random;
|
||||
if (all_off) begin
|
||||
chan0valid <= 1'b0;
|
||||
chan1valid <= 1'b0;
|
||||
chan2valid <= 1'b0;
|
||||
chan3valid <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
chan0valid <= $random | $random;
|
||||
chan1valid <= $random | $random;
|
||||
chan2valid <= $random | $random;
|
||||
chan3valid <= $random | $random;
|
||||
end
|
||||
end
|
||||
|
||||
////////////////////////////////////////
|
||||
// Inspect the recovered data
|
||||
////////////////////////////////////////
|
||||
reg fail = 1'b0;
|
||||
reg [64*NUM_DAT_WORDS-1:0] last_chan0,last_chan1,last_chan2,last_chan3;
|
||||
always @(posedge clk) begin
|
||||
#1
|
||||
if (ready && chan == 8'h0 && |num_datwords_valid) begin
|
||||
last_chan0 <= datwords;
|
||||
if (datwords == last_chan0) begin
|
||||
$display ("Repeated data on channel 0 at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
if (datwords[64*NUM_DAT_WORDS-1:64*NUM_DAT_WORDS-5*8] != "chan0") begin
|
||||
$display ("Channel 0 data tag mismatch");
|
||||
fail = 1;
|
||||
end
|
||||
end
|
||||
if (ready && chan == 8'h1 && |num_datwords_valid) begin
|
||||
last_chan1 <= datwords;
|
||||
if (datwords == last_chan1) begin
|
||||
$display ("Repeated data on channel 1 at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
if (datwords[64*NUM_DAT_WORDS-1:64*NUM_DAT_WORDS-5*8] != "chan1") begin
|
||||
$display ("Channel 1 data tag mismatch");
|
||||
fail = 1;
|
||||
end
|
||||
end
|
||||
if (ready && chan == 8'h2 && |num_datwords_valid) begin
|
||||
last_chan2 <= datwords;
|
||||
if (datwords == last_chan2) begin
|
||||
$display ("Repeated data on channel 2 at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
if (datwords[64*NUM_DAT_WORDS-1:64*NUM_DAT_WORDS-5*8] != "chan2") begin
|
||||
$display ("Channel 2 data tag mismatch");
|
||||
fail = 1;
|
||||
end
|
||||
end
|
||||
if (ready && chan == 8'h3 && |num_datwords_valid) begin
|
||||
last_chan3 <= datwords;
|
||||
if (datwords == last_chan3) begin
|
||||
$display ("Repeated data on channel 3 at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
if (datwords[64*NUM_DAT_WORDS-1:64*NUM_DAT_WORDS-5*8] != "chan3") begin
|
||||
$display ("Channel 3 data tag mismatch");
|
||||
fail = 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
////////////////////////////////////////
|
||||
// clock driver
|
||||
////////////////////////////////////////
|
||||
initial begin
|
||||
clk = 0;
|
||||
arst = 0;
|
||||
#1 arst = 1'b1;
|
||||
@(negedge clk) arst = 1'b0;
|
||||
end
|
||||
|
||||
always begin
|
||||
#5 clk = ~clk;
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
106
Advanced Synthesis Cookbook/arithmetic/adder_tree.v
Normal file
106
Advanced Synthesis Cookbook/arithmetic/adder_tree.v
Normal file
@ -0,0 +1,106 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 01-02-2007
|
||||
|
||||
module adder_tree (clk,in_words,out,extra_bit_in,extra_bit_out);
|
||||
|
||||
parameter NUM_IN_WORDS = 5;
|
||||
parameter NUM_IN_PAIRS = NUM_IN_WORDS / 2;
|
||||
parameter NUM_IN_ODD = NUM_IN_WORDS - NUM_IN_PAIRS * 2;
|
||||
parameter BITS_PER_IN_WORD = 13;
|
||||
parameter OUT_BITS = 29;
|
||||
parameter SIGN_EXT = 1; // bool - sign vs 0 extend
|
||||
parameter REGISTER_MIDDLE = 0; // bool - register within adders or not
|
||||
parameter REGISTER_OUTPUT = 1; // bool - register adder outputs or not
|
||||
parameter SHIFT_DIST = 1; // for multiplication - a shift between words
|
||||
parameter EXTRA_BIT_USED = 0; // extra bit to pass along the pipeline
|
||||
|
||||
// properties of the 1st layer output
|
||||
// Guess the number of output bits, if the guess is more than
|
||||
// the final requirement cap it.
|
||||
parameter LAYER_OUT_WORDS = NUM_IN_PAIRS + NUM_IN_ODD;
|
||||
parameter LAYER_OUT_EST_BITS = BITS_PER_IN_WORD + 1 + SHIFT_DIST;
|
||||
parameter LAYER_OUT_BITS = (OUT_BITS < LAYER_OUT_EST_BITS) ? OUT_BITS : LAYER_OUT_EST_BITS;
|
||||
|
||||
input clk;
|
||||
input extra_bit_in;
|
||||
output extra_bit_out;
|
||||
|
||||
input [NUM_IN_WORDS*BITS_PER_IN_WORD-1:0] in_words;
|
||||
output [OUT_BITS-1:0] out;
|
||||
|
||||
generate
|
||||
if (NUM_IN_WORDS == 1) begin
|
||||
if (OUT_BITS > BITS_PER_IN_WORD) begin
|
||||
// the output needs to be extended more
|
||||
initial begin
|
||||
$display ("Excess output width not currently supported");
|
||||
$stop();
|
||||
end
|
||||
end
|
||||
|
||||
// no more pipe, just tie off the wires and terminate recursion
|
||||
assign out = in_words;
|
||||
assign extra_bit_out = extra_bit_in;
|
||||
end
|
||||
else begin
|
||||
// knock out one horizontal slice of pairs
|
||||
wire [LAYER_OUT_WORDS*LAYER_OUT_BITS-1:0] layer_out;
|
||||
wire next_extra_bit;
|
||||
|
||||
adder_tree_layer al (
|
||||
.clk(clk),
|
||||
.in_words(in_words),
|
||||
.out_words(layer_out),
|
||||
.extra_bit_in(extra_bit_in),
|
||||
.extra_bit_out(next_extra_bit)
|
||||
);
|
||||
defparam al .NUM_IN_WORDS = NUM_IN_WORDS;
|
||||
defparam al .BITS_PER_IN_WORD = BITS_PER_IN_WORD;
|
||||
defparam al .BITS_PER_OUT_WORD = LAYER_OUT_BITS;
|
||||
defparam al .SIGN_EXT = SIGN_EXT;
|
||||
defparam al .REGISTER_OUTPUT = REGISTER_OUTPUT;
|
||||
defparam al .REGISTER_MIDDLE = REGISTER_MIDDLE;
|
||||
defparam al .SHIFT = SHIFT_DIST;
|
||||
defparam al .EXTRA_BIT_CONNECTED = EXTRA_BIT_USED;
|
||||
|
||||
// recurse on the remaining words
|
||||
adder_tree at (
|
||||
.clk(clk),
|
||||
.in_words(layer_out),
|
||||
.out(out),
|
||||
.extra_bit_in(next_extra_bit),
|
||||
.extra_bit_out(extra_bit_out)
|
||||
);
|
||||
defparam at .NUM_IN_WORDS = LAYER_OUT_WORDS;
|
||||
defparam at .BITS_PER_IN_WORD = LAYER_OUT_BITS;
|
||||
defparam at .OUT_BITS = OUT_BITS;
|
||||
defparam at .SIGN_EXT = SIGN_EXT;
|
||||
defparam at .REGISTER_OUTPUT = REGISTER_OUTPUT;
|
||||
defparam at .REGISTER_MIDDLE = REGISTER_MIDDLE;
|
||||
defparam at .SHIFT_DIST = SHIFT_DIST * 2;
|
||||
defparam at .EXTRA_BIT_USED = EXTRA_BIT_USED;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
110
Advanced Synthesis Cookbook/arithmetic/adder_tree_layer.v
Normal file
110
Advanced Synthesis Cookbook/arithmetic/adder_tree_layer.v
Normal file
@ -0,0 +1,110 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 01-02-2007
|
||||
// a horizontal slice of an adder tree
|
||||
|
||||
module adder_tree_layer (clk,in_words,out_words,extra_bit_in,extra_bit_out);
|
||||
|
||||
parameter NUM_IN_WORDS = 5;
|
||||
parameter NUM_IN_PAIRS = NUM_IN_WORDS / 2;
|
||||
parameter NUM_IN_ODD = NUM_IN_WORDS - NUM_IN_PAIRS * 2;
|
||||
parameter NUM_OUT_WORDS = NUM_IN_PAIRS + NUM_IN_ODD;
|
||||
|
||||
parameter BITS_PER_IN_WORD = 16;
|
||||
parameter BITS_PER_OUT_WORD = 17;
|
||||
parameter SIGN_EXT = 1;
|
||||
parameter REGISTER_MIDDLE = 0;
|
||||
parameter REGISTER_OUTPUT = 1;
|
||||
parameter SHIFT = 1; // apply to odd numbered words
|
||||
|
||||
parameter EXTRA_BIT_CONNECTED = 0; // pass extra bit along pipeline
|
||||
|
||||
input clk;
|
||||
input [NUM_IN_WORDS * BITS_PER_IN_WORD - 1 : 0] in_words;
|
||||
output [NUM_OUT_WORDS * BITS_PER_OUT_WORD -1 :0] out_words;
|
||||
input extra_bit_in;
|
||||
output extra_bit_out;
|
||||
reg extra_bit_m,extra_bit_out;
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
if (EXTRA_BIT_CONNECTED) begin
|
||||
if (REGISTER_MIDDLE) begin
|
||||
always @(posedge clk) extra_bit_m <= extra_bit_in;
|
||||
end
|
||||
else begin
|
||||
always @(*) extra_bit_m = extra_bit_in;
|
||||
end
|
||||
if (REGISTER_OUTPUT) begin
|
||||
always @(posedge clk) extra_bit_out <= extra_bit_m;
|
||||
end
|
||||
else begin
|
||||
always @(*) extra_bit_out = extra_bit_m;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
always @(*) extra_bit_out = 1'b0;
|
||||
end
|
||||
|
||||
// process the pairs as binary adder nodes with optional pipeline
|
||||
for (i=0; i<NUM_IN_PAIRS; i=i+1)
|
||||
begin : ad
|
||||
wire [2*BITS_PER_IN_WORD-1:0] node_ins;
|
||||
assign node_ins = in_words[2*(i+1)*BITS_PER_IN_WORD-1:
|
||||
2*i*BITS_PER_IN_WORD];
|
||||
adder_tree_node an (
|
||||
.clk(clk),
|
||||
.a(node_ins[BITS_PER_IN_WORD-1:0]),
|
||||
.b(node_ins[2*BITS_PER_IN_WORD-1:BITS_PER_IN_WORD]),
|
||||
.out(out_words[(i+1)*BITS_PER_OUT_WORD-1:
|
||||
i*BITS_PER_OUT_WORD]));
|
||||
defparam an .IN_BITS = BITS_PER_IN_WORD;
|
||||
defparam an .OUT_BITS = BITS_PER_OUT_WORD;
|
||||
defparam an .SIGN_EXT = SIGN_EXT;
|
||||
defparam an .REGISTER_OUTPUT = REGISTER_OUTPUT;
|
||||
defparam an .REGISTER_MIDDLE = REGISTER_MIDDLE;
|
||||
defparam an .B_SHIFT = SHIFT;
|
||||
end
|
||||
|
||||
// process any odd fall-through words
|
||||
if (NUM_IN_ODD) begin
|
||||
// treat this like a +0 to maintain the sign extension
|
||||
// and pipeline behavior with minimum fuss
|
||||
adder_tree_node an (
|
||||
.clk(clk),
|
||||
.a(in_words[BITS_PER_IN_WORD*NUM_IN_WORDS-1:
|
||||
BITS_PER_IN_WORD*(NUM_IN_WORDS-1)]),
|
||||
.b({BITS_PER_IN_WORD{1'b0}}),
|
||||
.out(out_words[(NUM_IN_PAIRS+1)*BITS_PER_OUT_WORD-1:
|
||||
NUM_IN_PAIRS*BITS_PER_OUT_WORD]));
|
||||
defparam an .IN_BITS = BITS_PER_IN_WORD;
|
||||
defparam an .OUT_BITS = BITS_PER_OUT_WORD;
|
||||
defparam an .SIGN_EXT = SIGN_EXT;
|
||||
defparam an .REGISTER_OUTPUT = REGISTER_OUTPUT;
|
||||
defparam an .REGISTER_MIDDLE = REGISTER_MIDDLE;
|
||||
defparam an .B_SHIFT = SHIFT;
|
||||
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
105
Advanced Synthesis Cookbook/arithmetic/adder_tree_node.v
Normal file
105
Advanced Synthesis Cookbook/arithmetic/adder_tree_node.v
Normal file
@ -0,0 +1,105 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 01-02-2007
|
||||
// a relatively fancy adder tree node
|
||||
|
||||
module adder_tree_node (clk,a,b,out);
|
||||
|
||||
parameter IN_BITS = 16;
|
||||
parameter OUT_BITS = 17;
|
||||
parameter SIGN_EXT = 1;
|
||||
parameter REGISTER_MIDDLE = 0; // register within adder chains
|
||||
parameter REGISTER_OUTPUT = 1; // register adder outputs
|
||||
parameter B_SHIFT = 1;
|
||||
|
||||
// for the placement of the midway pipeline registers
|
||||
localparam LS_WIDTH = OUT_BITS / 2;
|
||||
localparam MS_WIDTH = OUT_BITS - LS_WIDTH;
|
||||
|
||||
input clk;
|
||||
input [IN_BITS-1:0] a,b;
|
||||
output [OUT_BITS-1:0] out;
|
||||
|
||||
// sign extension
|
||||
wire [OUT_BITS-1:0] a_ext,b_ext;
|
||||
generate
|
||||
if (SIGN_EXT) begin
|
||||
assign a_ext = {{(OUT_BITS-IN_BITS){a[IN_BITS-1]}},a};
|
||||
assign b_ext = {{(OUT_BITS-IN_BITS){b[IN_BITS-1]}},b};
|
||||
end
|
||||
else begin
|
||||
assign a_ext = {{(OUT_BITS-IN_BITS){1'b0}},a};
|
||||
assign b_ext = {{(OUT_BITS-IN_BITS){1'b0}},b};
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// offset B
|
||||
wire [OUT_BITS-1:0] b_ext_shft;
|
||||
assign b_ext_shft = b_ext << B_SHIFT;
|
||||
|
||||
// addition
|
||||
wire [OUT_BITS-1:0] sum;
|
||||
generate
|
||||
if (REGISTER_MIDDLE) begin
|
||||
|
||||
// pipeline in the middle of the adder chain
|
||||
reg [LS_WIDTH-1+1:0] ls_adder;
|
||||
wire cross_carry = ls_adder[LS_WIDTH];
|
||||
always @(posedge clk) begin
|
||||
ls_adder <= {1'b0,a_ext[LS_WIDTH-1:0]} + {1'b0,b_ext_shft[LS_WIDTH-1:0]};
|
||||
end
|
||||
|
||||
reg [MS_WIDTH-1:0] ms_data_a,ms_data_b;
|
||||
always @(posedge clk) begin
|
||||
ms_data_a <= a_ext[OUT_BITS-1:OUT_BITS-MS_WIDTH];
|
||||
ms_data_b <= b_ext_shft[OUT_BITS-1:OUT_BITS-MS_WIDTH];
|
||||
end
|
||||
|
||||
wire [MS_WIDTH-1+1:0] ms_adder;
|
||||
assign ms_adder = {ms_data_a,cross_carry} +
|
||||
{ms_data_b,cross_carry};
|
||||
|
||||
assign sum = {ms_adder[MS_WIDTH:1],ls_adder[LS_WIDTH-1:0]};
|
||||
end
|
||||
else begin
|
||||
// simple addition
|
||||
assign sum = a_ext + b_ext_shft;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// optional output register
|
||||
reg [OUT_BITS-1:0] out;
|
||||
generate
|
||||
if (REGISTER_OUTPUT) begin
|
||||
always @(posedge clk) begin
|
||||
out <= sum;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
always @(*) begin
|
||||
out = sum;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
94
Advanced Synthesis Cookbook/arithmetic/adder_tree_tb.v
Normal file
94
Advanced Synthesis Cookbook/arithmetic/adder_tree_tb.v
Normal file
@ -0,0 +1,94 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 01-02-2007
|
||||
|
||||
module adder_tree_tb ();
|
||||
|
||||
reg [7:0] a,b,c;
|
||||
reg clk;
|
||||
wire [3*8-1:0] in_words;
|
||||
|
||||
assign in_words = {c,b,a};
|
||||
|
||||
initial begin
|
||||
a = 0;
|
||||
b = 0;
|
||||
c = 0;
|
||||
clk = 0;
|
||||
#10000000
|
||||
$display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
wire [9:0] out_at0, simple_sum;
|
||||
assign simple_sum = a + b + c;
|
||||
|
||||
adder_tree at0 (.clk(clk),.in_words(in_words),.out(out_at0),
|
||||
.extra_bit_in(1'b0),.extra_bit_out());
|
||||
defparam at0 .NUM_IN_WORDS = 3;
|
||||
defparam at0 .BITS_PER_IN_WORD = 8;
|
||||
defparam at0 .OUT_BITS = 10;
|
||||
defparam at0 .SIGN_EXT = 0;
|
||||
defparam at0 .REGISTER_OUTPUT = 0;
|
||||
defparam at0 .REGISTER_MIDDLE = 0;
|
||||
defparam at0 .SHIFT_DIST = 0;
|
||||
defparam at0 .EXTRA_BIT_USED = 0;
|
||||
|
||||
wire [11:0] out_at1, shifted_sum;
|
||||
assign shifted_sum = a + (b << 1) + (c << 2);
|
||||
|
||||
adder_tree at1 (.clk(clk),.in_words(in_words),.out(out_at1),
|
||||
.extra_bit_in(1'b0),.extra_bit_out());
|
||||
defparam at1 .NUM_IN_WORDS = 3;
|
||||
defparam at1 .BITS_PER_IN_WORD = 8;
|
||||
defparam at1 .OUT_BITS = 12;
|
||||
defparam at1 .SIGN_EXT = 0;
|
||||
defparam at1 .REGISTER_OUTPUT = 0;
|
||||
defparam at1 .REGISTER_MIDDLE = 0;
|
||||
defparam at1 .SHIFT_DIST = 1;
|
||||
defparam at1 .EXTRA_BIT_USED = 0;
|
||||
|
||||
always @(negedge clk) begin
|
||||
a = $random();
|
||||
b = $random();
|
||||
c = $random();
|
||||
end
|
||||
|
||||
always begin
|
||||
#100 clk = ~clk;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
#10
|
||||
if (out_at0 !== simple_sum) begin
|
||||
$display ("Mismatch on no-shift addition at time %d",$time);
|
||||
$stop();
|
||||
end
|
||||
if (out_at1 !== shifted_sum) begin
|
||||
$display ("Mismatch on shift addition at time %d",$time);
|
||||
$stop();
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
83
Advanced Synthesis Cookbook/arithmetic/addsub.v
Normal file
83
Advanced Synthesis Cookbook/arithmetic/addsub.v
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module addsub (sub,a,b,o);
|
||||
|
||||
parameter WIDTH = 16;
|
||||
parameter METHOD = 1;
|
||||
|
||||
input sub;
|
||||
input [WIDTH-1:0] a,b;
|
||||
output [WIDTH:0] o;
|
||||
|
||||
generate
|
||||
if (METHOD == 0) begin
|
||||
// generic style
|
||||
assign o = sub ? (a - b) : (a + b);
|
||||
end
|
||||
else if (METHOD == 1) begin
|
||||
// Hardware implementation with XORs in front of a
|
||||
// carry chain.
|
||||
wire [WIDTH+1:0] tmp;
|
||||
assign tmp = {1'b0,a,sub} + {sub,{WIDTH{sub}} ^ b,sub};
|
||||
assign o = tmp[WIDTH+1:1];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
/////////////////////////////////////
|
||||
|
||||
module addsub_tb ();
|
||||
parameter WIDTH = 16;
|
||||
|
||||
reg [WIDTH-1:0] a,b;
|
||||
reg sub,fail;
|
||||
wire [WIDTH:0] ox,oy;
|
||||
|
||||
initial begin
|
||||
a = 0;
|
||||
b = 0;
|
||||
fail = 0;
|
||||
#100000 if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
addsub x (.a(a),.b(b),.sub(sub),.o(ox));
|
||||
defparam x .WIDTH = WIDTH;
|
||||
defparam x .METHOD = 0;
|
||||
|
||||
addsub y (.a(a),.b(b),.sub(sub),.o(oy));
|
||||
defparam y .WIDTH = WIDTH;
|
||||
defparam y .METHOD = 1;
|
||||
|
||||
always begin
|
||||
#50 a = $random;
|
||||
b = $random;
|
||||
sub = $random;
|
||||
#50
|
||||
if (ox !== oy) begin
|
||||
$display ("Mismatch at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
end
|
||||
endmodule
|
174
Advanced Synthesis Cookbook/arithmetic/basic_adder.v
Normal file
174
Advanced Synthesis Cookbook/arithmetic/basic_adder.v
Normal file
@ -0,0 +1,174 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 10-24-2006
|
||||
// example of bit slicing v.s. word adders on Stratix II
|
||||
|
||||
///////////////////////////////////////////////
|
||||
//
|
||||
// This is the basic "+" operator version. It is
|
||||
// easy to use and gives the synthesis tool an
|
||||
// unambiguous message of which bits belong together.
|
||||
// The synthesis tool has permission to minimize and
|
||||
// restructure "+" operations freely. For example to
|
||||
// change "1+a+1" to "a+2". This is the method
|
||||
// recommended by Altera and 3rd party synthesis.
|
||||
//
|
||||
module word_adder_plain (a,b,s);
|
||||
parameter WIDTH = 8;
|
||||
|
||||
input [WIDTH-1:0] a,b;
|
||||
output [WIDTH-1:0] s;
|
||||
|
||||
assign s = a + b;
|
||||
|
||||
endmodule
|
||||
|
||||
///////////////////////////////////////////////
|
||||
//
|
||||
// This is a standard Full Adder cell expressed
|
||||
// in a WYSIWYG gate. This form is preferable
|
||||
// to comb logic because it explicitly marks the
|
||||
// carry in and carry out. It is also a good
|
||||
// way to express complex logic functions on the
|
||||
// input side of the adder, and shared chains
|
||||
// (ternary addition). This view gives access
|
||||
// to all architecture capabilities, but is somewhat
|
||||
// cumbersome to use. Unlike the "+" operator
|
||||
// a WYSIWYG add will not be restructured or
|
||||
// mimnimized except in extreme cases.
|
||||
//
|
||||
module full_add (a,b,cin,s,cout);
|
||||
input a,b,cin;
|
||||
output s,cout;
|
||||
|
||||
stratixii_lcell_comb w (
|
||||
.dataa(1'b1),
|
||||
.datab(1'b1),
|
||||
.datac(1'b1),
|
||||
.datad(a),
|
||||
.datae(1'b1),
|
||||
.dataf(b),
|
||||
.datag(1'b1),
|
||||
|
||||
.cin(cin),
|
||||
.sharein(1'b0),
|
||||
.sumout(s),
|
||||
.cout(cout),
|
||||
.combout(),
|
||||
.shareout()
|
||||
);
|
||||
|
||||
defparam w .shared_arith = "off";
|
||||
defparam w .extended_lut = "off";
|
||||
defparam w .lut_mask = 64'h000000ff0000ff00 ;
|
||||
|
||||
//
|
||||
// Note : LUT mask programming is generally done by
|
||||
// synthesis software, but they can be set by hand. This
|
||||
// explanation is for the interested person, and by
|
||||
// no means necessary to follow.
|
||||
//
|
||||
// The lut mask is a truth table expressed in 64 bit hex.
|
||||
// In basic adder mode these two blocks are active.
|
||||
// vvvv vvvv
|
||||
// 64'h000000ff0000ff00
|
||||
//
|
||||
// Each 4 hex digit block represents a function of up to 4 inputs.
|
||||
// The left hand block uses "ABCF" and the right hand "ABCD" with
|
||||
// A being the least significant. For each of the 16 possible input
|
||||
// values the function output is stored in the corresponting bit.
|
||||
//
|
||||
// e.g. ffff = vcc (all ones)
|
||||
// ff00 = "D" (most significant)
|
||||
// aaaa = "A" (1010..binary, the least significant)
|
||||
// 6666 = "A xor B"
|
||||
//
|
||||
// These functions will be the two inputs to the adder chain.
|
||||
// In this case the inputs D and F pass through. Detailed
|
||||
// information on the programming of WYSIWYG cells is available
|
||||
// through the Altera University Program (for CAD tools
|
||||
// research).
|
||||
//
|
||||
|
||||
endmodule
|
||||
|
||||
///////////////////////////////////////////////
|
||||
//
|
||||
// This is a word adder constructed from the
|
||||
// slices declared above.
|
||||
//
|
||||
module word_adder_sliced (a,b,s);
|
||||
parameter WIDTH = 8;
|
||||
|
||||
input [WIDTH-1:0] a,b;
|
||||
output [WIDTH-1:0] s;
|
||||
wire [WIDTH:0] cin;
|
||||
|
||||
assign cin[0] = 1'b0;
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for (i=0; i<WIDTH; i=i+1)
|
||||
begin : al
|
||||
full_add fa (.a(a[i]),.b(b[i]),.cin(cin[i]),.s(s[i]),.cout(cin[i+1]));
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
///////////////////////////////////////////////
|
||||
//
|
||||
// This verifies that the "+" and bit sliced
|
||||
// chain have identical behavior
|
||||
//
|
||||
module adder_testbench ();
|
||||
|
||||
parameter WIDTH = 12;
|
||||
reg [WIDTH-1:0] a,b;
|
||||
wire [WIDTH-1:0] o1,o2;
|
||||
|
||||
// adders to compare
|
||||
word_adder_plain ap (.a(a),.b(b),.s(o1));
|
||||
defparam ap .WIDTH = WIDTH;
|
||||
|
||||
word_adder_sliced as (.a(a),.b(b),.s(o2));
|
||||
defparam as .WIDTH = WIDTH;
|
||||
|
||||
reg fail;
|
||||
initial begin
|
||||
a = 0; b = 0;
|
||||
fail = 0;
|
||||
#1000000 if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
always begin
|
||||
#100 a = $random; b = $random;
|
||||
#10 if (o1 !== o2) begin
|
||||
$display ("Mismatch at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
36
Advanced Synthesis Cookbook/arithmetic/compress_32.v
Normal file
36
Advanced Synthesis Cookbook/arithmetic/compress_32.v
Normal file
@ -0,0 +1,36 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module compress_32 (a,b,c,oo,ot);
|
||||
parameter WIDTH = 16;
|
||||
input [WIDTH-1:0] a,b,c;
|
||||
output [WIDTH-1:0] oo,ot;
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for (i=0; i<WIDTH; i=i+1)
|
||||
begin : cmp
|
||||
assign oo[i] = a[i] ^ b[i] ^ c[i];
|
||||
assign ot[i] = (a[i] & b[i]) | (a[i] & c[i]) | (b[i] & c[i]);
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
182
Advanced Synthesis Cookbook/arithmetic/cordic.v
Normal file
182
Advanced Synthesis Cookbook/arithmetic/cordic.v
Normal file
@ -0,0 +1,182 @@
|
||||
// Copyright 2008 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 08-04-2008
|
||||
|
||||
module cordic
|
||||
#(parameter WIDTH = 16) // note : update ROM content if changing this parameter
|
||||
(
|
||||
input clk,sclr,
|
||||
input xi,yi,zi,
|
||||
input rot,
|
||||
output valid,
|
||||
output xo,yo,zo
|
||||
);
|
||||
|
||||
////////////////////
|
||||
// control
|
||||
////////////////////
|
||||
reg [3:0] round_num;
|
||||
reg [3:0] bits_left;
|
||||
reg sign_ext;
|
||||
reg round_num_max;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (sclr) begin
|
||||
round_num <= 0;
|
||||
bits_left <= 4'hf;
|
||||
sign_ext <= 1'b0;
|
||||
round_num_max <= 0;
|
||||
end
|
||||
else begin
|
||||
bits_left <= bits_left - 1'b1;
|
||||
if (bits_left == round_num) sign_ext <= 1'b1;
|
||||
if (~|bits_left) begin
|
||||
round_num_max <= (round_num == 4'hc); // count 0..d
|
||||
sign_ext <= 1'b0;
|
||||
if (round_num_max) round_num <= 0;
|
||||
else round_num <= round_num + 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
wire isel = round_num_max;
|
||||
assign valid = isel;
|
||||
|
||||
////////////////////
|
||||
// iterative adders
|
||||
////////////////////
|
||||
reg [WIDTH-1:0] x,y,z,zrom;
|
||||
wire xsum,ysum,zsum, xshift, yshift;
|
||||
reg d;
|
||||
|
||||
wire first = &bits_left;
|
||||
iter_addsub xa (.clk(clk),.sclr(sclr),.a(x[0]), .b(yshift),
|
||||
.first(first),.sub(d),.sum(xsum));
|
||||
iter_addsub ya (.clk(clk),.sclr(sclr),.a(y[0]), .b(xshift),
|
||||
.first(first),.sub(!d),.sum(ysum));
|
||||
iter_addsub za (.clk(clk),.sclr(sclr),.a(z[0]), .b(zrom[0]),
|
||||
.first(first),.sub(d),.sum(zsum));
|
||||
|
||||
//////////////////////////////////
|
||||
// grab registers for sign extend
|
||||
//////////////////////////////////
|
||||
reg last_xshift,last_yshift;
|
||||
always @(posedge clk) begin
|
||||
if (sclr) begin
|
||||
last_xshift <= 1'b0;
|
||||
last_yshift <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
last_yshift <= yshift;
|
||||
last_xshift <= xshift;
|
||||
end
|
||||
end
|
||||
|
||||
//////////////////////////////////
|
||||
// debug monitor
|
||||
//////////////////////////////////
|
||||
// synthesis translate off
|
||||
always @(posedge clk) begin
|
||||
if (first) begin
|
||||
$display ("Round %d",round_num);
|
||||
$display (" x=%b (%d)",x,x);
|
||||
$display (" y=%b (%d)",y,y);
|
||||
$display (" z=%b (%d)",z,z);
|
||||
$display (" zrom=%b (%d)",zrom,zrom);
|
||||
end
|
||||
end
|
||||
// synthesis translate on
|
||||
|
||||
//////////////////////////////////
|
||||
// depending on the mode, minimize
|
||||
// y or z register
|
||||
//////////////////////////////////
|
||||
always @(posedge clk) begin
|
||||
if (sclr) d <= 0;
|
||||
else begin
|
||||
if (~|bits_left) begin
|
||||
if (rot) d <= !(isel ? zi : zsum);
|
||||
else d <= (isel ? yi : ysum);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//////////////////////////////////
|
||||
// XYZ shift registers
|
||||
//////////////////////////////////
|
||||
always @(posedge clk) begin
|
||||
if (sclr) begin
|
||||
x <= 0;
|
||||
y <= 0;
|
||||
z <= 0;
|
||||
end
|
||||
else begin
|
||||
x <= {(isel ? xi : xsum),x[WIDTH-1:1]};
|
||||
y <= {(isel ? yi : ysum),y[WIDTH-1:1]};
|
||||
z <= {(isel ? zi : zsum),z[WIDTH-1:1]};
|
||||
end
|
||||
end
|
||||
assign xshift = sign_ext ? last_xshift : x[round_num];
|
||||
assign yshift = sign_ext ? last_yshift : y[round_num];
|
||||
assign xo = x[0];
|
||||
assign yo = y[0];
|
||||
assign zo = z[0];
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
// This is a little ROM of the arctangent of 2^-i in radians
|
||||
// MSB weight is -2
|
||||
// next is 1
|
||||
// next is 0.5 and so on
|
||||
// The indexing is off by one to load the constant associated
|
||||
// with the NEXT round.
|
||||
//////////////////////////////////////////////////////////////
|
||||
wire zrom_load = ~|bits_left;
|
||||
always @(posedge clk) begin
|
||||
if (sclr) zrom <= 1'b0;
|
||||
else if (zrom_load) begin
|
||||
case (round_num)
|
||||
4'hd : zrom <= 16'b0011001001000011; // 0.78539816
|
||||
4'h0 : zrom <= 16'b0001110110101100; // 0.46364761
|
||||
4'h1 : zrom <= 16'b0000111110101101; // 0.24497866
|
||||
4'h2 : zrom <= 16'b0000011111110101; // 0.12435499
|
||||
4'h3 : zrom <= 16'b0000001111111110; // 0.06241881
|
||||
4'h4 : zrom <= 16'b0000000111111111; // 0.03123983
|
||||
4'h5 : zrom <= 16'b0000000011111111; // 0.01562373
|
||||
4'h6 : zrom <= 16'b0000000001111111; // 0.00781234
|
||||
4'h7 : zrom <= 16'b0000000000111111; // 0.00390623
|
||||
4'h8 : zrom <= 16'b0000000000011111; // 0.00195312
|
||||
4'h9 : zrom <= 16'b0000000000001111; // 0.00097656
|
||||
4'ha : zrom <= 16'b0000000000000111; // 0.00048828
|
||||
4'hb : zrom <= 16'b0000000000000011; // 0.00024414
|
||||
4'hc : zrom <= 16'b0000000000000001; // 0.00012207
|
||||
|
||||
// these are unused
|
||||
4'he : zrom <= 16'b0000000000000000; // 0.00006104
|
||||
4'hf : zrom <= 16'b0000000000000000; // 0.00003052
|
||||
endcase
|
||||
end
|
||||
else zrom <= {1'b0,zrom[WIDTH-1:1]};
|
||||
end
|
||||
|
||||
endmodule
|
161
Advanced Synthesis Cookbook/arithmetic/cordic_angle_table.cpp
Normal file
161
Advanced Synthesis Cookbook/arithmetic/cordic_angle_table.cpp
Normal file
@ -0,0 +1,161 @@
|
||||
// Copyright 2008 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 08-06-2008
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
////////////////////////////////////////
|
||||
// convert float to fixed point signed binary
|
||||
// values must be in the range -2..2
|
||||
////////////////////////////////////////
|
||||
void conv_binary (double val, int bits)
|
||||
{
|
||||
double f;
|
||||
int n = 0;
|
||||
|
||||
fprintf (stdout,"%d'b",bits);
|
||||
|
||||
// handle the top bit to become positive
|
||||
if (val < 0.0)
|
||||
{
|
||||
fprintf (stdout,"1");
|
||||
val += 2.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stdout,"0");
|
||||
}
|
||||
|
||||
// handle remaining bits
|
||||
for (n=0; n<bits-1; n++)
|
||||
{
|
||||
f = 1.0;
|
||||
f /= (1 << n);
|
||||
|
||||
if (val >= f)
|
||||
{
|
||||
fprintf (stdout,"1");
|
||||
val -= f;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stdout,"0");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////
|
||||
// generate an arctan table for CORDIC
|
||||
////////////////////////////////////////
|
||||
int main (void)
|
||||
{
|
||||
double f = 1.0, at=0.0;
|
||||
double pi = 3.14159265358979;
|
||||
double gain = 1.0, gain_term;
|
||||
|
||||
int const bits = 16;
|
||||
int const rounds = 16;
|
||||
|
||||
int n = 0;
|
||||
|
||||
// ROM content
|
||||
for (n=0; n<rounds; n++)
|
||||
{
|
||||
f = 1.0;
|
||||
f /= (1 << n);
|
||||
|
||||
gain_term = 1.0 + f*f;
|
||||
gain_term = sqrt(gain_term);
|
||||
gain *= gain_term;
|
||||
|
||||
at = atan(f);
|
||||
fprintf (stdout," 4'h%x : zrom <= ",n);
|
||||
conv_binary (at,bits);
|
||||
fprintf (stdout,"; // %1.8f\n",at);
|
||||
}
|
||||
|
||||
// handy constants for use in testing
|
||||
fprintf (stdout,"\n\n");
|
||||
|
||||
fprintf (stdout,"gain = ");
|
||||
conv_binary (gain,bits);
|
||||
fprintf (stdout," // %1.8f\n",gain);
|
||||
|
||||
fprintf (stdout,"inv_gain = ");
|
||||
conv_binary (1.0/gain,bits);
|
||||
fprintf (stdout," // %1.8f\n",1.0/gain);
|
||||
|
||||
f = pi / 8.0;
|
||||
fprintf (stdout,"pi_over_8 = ");
|
||||
conv_binary (f,bits);
|
||||
fprintf (stdout,"; // %1.8f\n",f);
|
||||
|
||||
f = pi / 8.0;
|
||||
f = sin(f);
|
||||
fprintf (stdout,"sin_pi_over_8 = ");
|
||||
conv_binary (f,bits);
|
||||
fprintf (stdout,"; // %1.8f\n",f);
|
||||
|
||||
f = pi / 8.0;
|
||||
f = cos(f);
|
||||
fprintf (stdout,"cos_pi_over_8 = ");
|
||||
conv_binary (f,bits);
|
||||
fprintf (stdout,"; // %1.8f\n",f);
|
||||
|
||||
f = -pi / 3.0;
|
||||
fprintf (stdout,"neg_pi_over_3 = ");
|
||||
conv_binary (f,bits);
|
||||
fprintf (stdout,"; // %1.8f\n",f);
|
||||
|
||||
f = -pi / 3.0;
|
||||
f = sin(f);
|
||||
fprintf (stdout,"sin_neg_pi_over_3 = ");
|
||||
conv_binary (f,bits);
|
||||
fprintf (stdout,"; // %1.8f\n",f);
|
||||
|
||||
f = -pi / 3.0;
|
||||
f = cos(f);
|
||||
fprintf (stdout,"cos_neg_pi_over_3 = ");
|
||||
conv_binary (f,bits);
|
||||
fprintf (stdout,"; // %1.8f\n",f);
|
||||
|
||||
f = pi / 4.0;
|
||||
fprintf (stdout,"pi_over_4 = ");
|
||||
conv_binary (f,bits);
|
||||
fprintf (stdout,"; // %1.8f\n",f);
|
||||
|
||||
f = -pi / 4.0;
|
||||
fprintf (stdout,"neg_pi_over_4 = ");
|
||||
conv_binary (f,bits);
|
||||
fprintf (stdout,"; // %1.8f\n",f);
|
||||
|
||||
f = (0.25*0.25) + (0.25*0.25);
|
||||
f = sqrt(f) * gain;
|
||||
fprintf (stdout,"gained_vec_len = ");
|
||||
conv_binary (f,bits);
|
||||
fprintf (stdout,"; // %1.8f\n",f);
|
||||
|
||||
|
||||
return (0);
|
||||
}
|
155
Advanced Synthesis Cookbook/arithmetic/cordic_tb.v
Normal file
155
Advanced Synthesis Cookbook/arithmetic/cordic_tb.v
Normal file
@ -0,0 +1,155 @@
|
||||
// Copyright 2008 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 08-04-2008
|
||||
|
||||
module cordic_tb ();
|
||||
|
||||
// The output functions are approximations, this compares four signed 16 bit
|
||||
// words to expected values with some error margin.
|
||||
|
||||
function significant_error;
|
||||
input [63:0] a,b;
|
||||
integer n,diff;
|
||||
begin
|
||||
significant_error = 1'b0;
|
||||
|
||||
for (n=0; n<4; n=n+1)
|
||||
begin : cmp
|
||||
diff = {a[15],a[15:0]} - {b[15],b[15:0]};
|
||||
if (diff[16]) diff = -diff;
|
||||
diff = diff & 16'hffff;
|
||||
|
||||
// This means that an absolute deviation of +/- 8 points
|
||||
// is considered to be passing for testbench purposes.
|
||||
if (diff > 8) significant_error = 1'b1;
|
||||
|
||||
a = a >> 16;
|
||||
b = b >> 16;
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
|
||||
// test device
|
||||
reg clk,sclr;
|
||||
reg [4*16-1:0] xin,yin,zin,rot;
|
||||
reg [4*16-1:0] xout,yout,zout;
|
||||
wire xo,yo,zo;
|
||||
|
||||
cordic dut
|
||||
(
|
||||
.clk,
|
||||
.sclr,
|
||||
.xi(xin[0]),
|
||||
.yi(yin[0]),
|
||||
.zi(zin[0]),
|
||||
.rot(rot[0]),
|
||||
.valid(valid),
|
||||
.xo,
|
||||
.yo,
|
||||
.zo
|
||||
);
|
||||
|
||||
always begin
|
||||
#5 clk = ~clk;
|
||||
end
|
||||
|
||||
// constants for testing
|
||||
reg [15:0] gain = 16'b0110100101100100; // 1.64676026
|
||||
reg [15:0] inv_gain = 16'b0010011011011101; // 0.60725294
|
||||
reg [15:0] pi_over_8 = 16'b0001100100100001; // 0.39269908
|
||||
reg [15:0] sin_pi_over_8 = 16'b0001100001111101; // 0.38268343
|
||||
reg [15:0] cos_pi_over_8 = 16'b0011101100100000; // 0.92387953
|
||||
reg [15:0] neg_pi_over_3 = 16'b1011110011111010; // -1.04719755
|
||||
reg [15:0] sin_neg_pi_over_3 = 16'b1100100010010011; // -0.86602540
|
||||
reg [15:0] cos_neg_pi_over_3 = 16'b0010000000000000; // 0.50000000
|
||||
reg [15:0] pi_over_4 = 16'b0011001001000011; // 0.78539816
|
||||
reg [15:0] neg_pi_over_4 = 16'b1100110110111100; // -0.78539816
|
||||
reg [15:0] gained_vec_len = 16'b0010010101000011; // 0.58221767
|
||||
|
||||
|
||||
reg [4*16-1:0] expected_x;
|
||||
reg [4*16-1:0] expected_y;
|
||||
reg [4*16-1:0] expected_z;
|
||||
reg fail = 1'b0;
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
sclr = 0;
|
||||
|
||||
// Test questions :
|
||||
// find angle for [2,-2]
|
||||
// find angle for [1, 1]
|
||||
// find sin,cos for -pi / 3
|
||||
// find sin,cos for pi / 8
|
||||
xin = {16'h1000, 16'h1000, inv_gain, inv_gain};
|
||||
yin = {16'hf000, 16'h1000, 16'h0000, 16'h0000};
|
||||
zin = {16'h0000, 16'h0000, neg_pi_over_3,pi_over_8};
|
||||
rot = 1'b1;
|
||||
|
||||
expected_x = {gained_vec_len,gained_vec_len,cos_neg_pi_over_3,cos_pi_over_8};
|
||||
expected_y = {16'h0000,16'h0000,sin_neg_pi_over_3,sin_pi_over_8};
|
||||
expected_z = {neg_pi_over_4,pi_over_4,16'h0000,16'h0000};
|
||||
|
||||
@(negedge clk) sclr = 1'b1;
|
||||
@(negedge clk) sclr = 1'b0;
|
||||
|
||||
@(posedge valid);
|
||||
@(posedge valid);
|
||||
@(posedge valid);
|
||||
rot = 1'b0;
|
||||
@(posedge valid);
|
||||
@(posedge valid);
|
||||
@(negedge valid);
|
||||
|
||||
// check outputs
|
||||
if (significant_error (xout,expected_x)) begin
|
||||
$display ("Significant deviation between actual and expected X");
|
||||
fail = 1'b1;
|
||||
end
|
||||
if (significant_error (yout,expected_y)) begin
|
||||
$display ("Significant deviation between actual and expected Y");
|
||||
fail = 1'b1;
|
||||
end
|
||||
if (significant_error (zout,expected_z)) begin
|
||||
$display ("Significant deviation between actual and expected Z");
|
||||
fail = 1'b1;
|
||||
end
|
||||
|
||||
if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (valid) begin
|
||||
xin <= {xin[0],xin[4*16-1:1]};
|
||||
yin <= {yin[0],yin[4*16-1:1]};
|
||||
zin <= {zin[0],zin[4*16-1:1]};
|
||||
|
||||
xout <= {xo,xout[4*16-1:1]};
|
||||
yout <= {yo,yout[4*16-1:1]};
|
||||
zout <= {zo,zout[4*16-1:1]};
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
163
Advanced Synthesis Cookbook/arithmetic/divider.v
Normal file
163
Advanced Synthesis Cookbook/arithmetic/divider.v
Normal file
@ -0,0 +1,163 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 04-13-2006
|
||||
// unsigned iterative divider, 1 and 2 bit per clock
|
||||
// tick versions
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// 1 bit per tick version
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
module divider (clk,rst,load,n,d,q,r,ready);
|
||||
|
||||
`include "log2.inc"
|
||||
|
||||
parameter WIDTH_N = 32;
|
||||
parameter WIDTH_D = 32;
|
||||
localparam LOG2_WIDTH_N = log2(WIDTH_N);
|
||||
localparam MIN_ND = (WIDTH_N <WIDTH_D ? WIDTH_N : WIDTH_D);
|
||||
|
||||
input clk,rst;
|
||||
|
||||
input load; // load the numer and denominator
|
||||
input [WIDTH_N-1:0] n; // numerator
|
||||
input [WIDTH_D-1:0] d; // denominator
|
||||
output [WIDTH_N-1:0] q; // quotient
|
||||
output [WIDTH_D-1:0] r; // remainder
|
||||
output ready; // Q and R are valid now.
|
||||
|
||||
reg [WIDTH_N + MIN_ND : 0] working;
|
||||
reg [WIDTH_D-1 : 0] denom;
|
||||
|
||||
wire [WIDTH_N-1:0] lower_working = working [WIDTH_N-1:0];
|
||||
wire [MIN_ND:0] upper_working = working [WIDTH_N + MIN_ND : WIDTH_N];
|
||||
|
||||
wire [WIDTH_D:0] sub_result = upper_working - denom;
|
||||
wire sub_result_neg = sub_result[WIDTH_D];
|
||||
|
||||
reg [LOG2_WIDTH_N:0] cntr;
|
||||
wire cntr_zero = ~|cntr;
|
||||
assign ready = cntr_zero;
|
||||
|
||||
always @(posedge clk or posedge rst) begin
|
||||
if (rst) begin
|
||||
working <= 0;
|
||||
denom <= 0;
|
||||
cntr <= 0;
|
||||
end
|
||||
else begin
|
||||
if (load) begin
|
||||
working <= {{WIDTH_D{1'b0}},n,1'b0};
|
||||
cntr <= WIDTH_N;
|
||||
denom <= d;
|
||||
end
|
||||
else begin
|
||||
if (!cntr_zero) begin
|
||||
cntr <= cntr - 1;
|
||||
working <= sub_result_neg ? {working[WIDTH_N+MIN_ND-1:0],1'b0} :
|
||||
{sub_result[WIDTH_D-1:0],lower_working,1'b1};
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign q = lower_working;
|
||||
assign r = upper_working >> 1;
|
||||
|
||||
endmodule
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// 2 bits per tick (radix 4) version
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
module divider_rad4 (clk,rst,load,n,d,q,r,ready);
|
||||
|
||||
`include "log2.inc"
|
||||
|
||||
parameter WIDTH_N = 32; // assumed to be EVEN
|
||||
parameter WIDTH_D = 32;
|
||||
localparam LOG2_WIDTH_N = log2(WIDTH_N);
|
||||
localparam MIN_ND = (WIDTH_N <WIDTH_D ? WIDTH_N : WIDTH_D);
|
||||
|
||||
input clk,rst;
|
||||
|
||||
input load; // load the numer and denominator
|
||||
input [WIDTH_N-1:0] n; // numerator
|
||||
input [WIDTH_D-1:0] d; // denominator
|
||||
output [WIDTH_N-1:0] q; // quotient
|
||||
output [WIDTH_D-1:0] r; // remainder
|
||||
output ready; // Q and R are valid now.
|
||||
|
||||
reg [WIDTH_N + MIN_ND + 1 : 0] working;
|
||||
reg [WIDTH_D-1 : 0] denom;
|
||||
reg [WIDTH_D+1 : 0] triple_denom;
|
||||
|
||||
wire [WIDTH_N-1:0] lower_working = working [WIDTH_N-1:0];
|
||||
wire [MIN_ND + 1:0] upper_working = working [WIDTH_N + MIN_ND + 1: WIDTH_N];
|
||||
|
||||
wire [WIDTH_D + 2:0] minus_zero = upper_working;
|
||||
wire [WIDTH_D + 2:0] minus_one = upper_working - denom;
|
||||
wire [WIDTH_D + 2:0] minus_two = upper_working - (denom << 1);
|
||||
wire [WIDTH_D + 2:0] minus_three = upper_working - triple_denom;
|
||||
|
||||
wire [1:0] quot_bits = {!minus_two[WIDTH_D+2],
|
||||
!minus_one[WIDTH_D+2] &
|
||||
!(minus_three[WIDTH_D+2] ^ minus_two[WIDTH_D+2])};
|
||||
|
||||
wire [WIDTH_D + 2:0] appro_minus =
|
||||
quot_bits[1] ? (quot_bits[0] ? minus_three : minus_two) :
|
||||
(quot_bits[0] ? minus_one : minus_zero);
|
||||
|
||||
reg [LOG2_WIDTH_N:0] cntr;
|
||||
wire cntr_zero = ~|cntr;
|
||||
assign ready = cntr_zero;
|
||||
|
||||
always @(posedge clk or posedge rst) begin
|
||||
if (rst) begin
|
||||
working <= 0;
|
||||
denom <= 0;
|
||||
triple_denom <= 0;
|
||||
cntr <= 0;
|
||||
end
|
||||
else begin
|
||||
if (load) begin
|
||||
working <= {{MIN_ND{1'b0}},n,2'b0};
|
||||
cntr <= (WIDTH_N >> 1);
|
||||
denom <= d;
|
||||
triple_denom <= (d + (d << 1));
|
||||
end
|
||||
else begin
|
||||
if (!cntr_zero) begin
|
||||
cntr <= cntr - 1;
|
||||
working <= {appro_minus[WIDTH_D-1:0],lower_working,quot_bits};
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign q = lower_working;
|
||||
assign r = upper_working >> 2;
|
||||
|
||||
endmodule
|
||||
|
||||
|
142
Advanced Synthesis Cookbook/arithmetic/divider_tb.v
Normal file
142
Advanced Synthesis Cookbook/arithmetic/divider_tb.v
Normal file
@ -0,0 +1,142 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
// sanity check for divider.v
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
module divider_tb ();
|
||||
|
||||
parameter WIDTH_N = 10;
|
||||
parameter WIDTH_D = 10;
|
||||
|
||||
reg clk,rst,load;
|
||||
|
||||
reg [WIDTH_N-1:0] n;
|
||||
reg [WIDTH_D-1:0] d;
|
||||
wire [WIDTH_N-1:0] q_a,q_b;
|
||||
wire [WIDTH_D-1:0] r_a,r_b;
|
||||
wire ready_a,ready_b;
|
||||
|
||||
/////////////////
|
||||
// radix 4 DUT
|
||||
/////////////////
|
||||
divider_rad4 dva (.clk(clk),.rst(rst),.load(load),
|
||||
.n(n),.d(d),.q(q_a),.r(r_a),.ready(ready_a));
|
||||
|
||||
defparam dva .WIDTH_N = WIDTH_N;
|
||||
defparam dva .WIDTH_D = WIDTH_D;
|
||||
|
||||
/////////////////
|
||||
// plain DUT
|
||||
/////////////////
|
||||
divider dvb (.clk(clk),.rst(rst),.load(load),
|
||||
.n(n),.d(d),.q(q_b),.r(r_b),.ready(ready_b));
|
||||
|
||||
defparam dvb .WIDTH_N = WIDTH_N;
|
||||
defparam dvb .WIDTH_D = WIDTH_D;
|
||||
|
||||
/////////////////
|
||||
// simple model
|
||||
/////////////////
|
||||
integer expected_q = 0, expected_r = 0;
|
||||
always @(posedge clk or posedge rst) begin
|
||||
if (rst) begin
|
||||
expected_q <= 0;
|
||||
expected_r <= 0;
|
||||
end
|
||||
else begin
|
||||
if (load) begin
|
||||
expected_q <= n/d;
|
||||
expected_r <= n%d;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
/////////////////
|
||||
// start test
|
||||
/////////////////
|
||||
reg fail;
|
||||
initial begin
|
||||
clk = 0;
|
||||
rst = 0;
|
||||
fail = 0;
|
||||
load = 0;
|
||||
#10 rst = 1;
|
||||
#10 rst = 0;
|
||||
#10000000 if (!fail) $display ("PASS"); else $display ("FAIL");
|
||||
$display ("%d correct answers",tests);
|
||||
$stop;
|
||||
end
|
||||
|
||||
|
||||
always begin
|
||||
#100 clk = ~clk;
|
||||
end
|
||||
|
||||
////////////////////
|
||||
// stim generation
|
||||
////////////////////
|
||||
integer tests = 0;
|
||||
always @(posedge clk) begin
|
||||
#10
|
||||
if (!load & ready_a & ready_b)
|
||||
begin
|
||||
@(negedge clk);
|
||||
load = 1;
|
||||
n = $random;
|
||||
d = $random;
|
||||
// don't divide by zero
|
||||
if (d == 0) d = 1;
|
||||
|
||||
@(posedge clk);
|
||||
@(negedge clk);
|
||||
load = 0;
|
||||
tests = tests + 1;
|
||||
end
|
||||
end
|
||||
|
||||
////////////////////
|
||||
// answer checking
|
||||
////////////////////
|
||||
always @(posedge ready_a)
|
||||
begin
|
||||
#10
|
||||
if (q_a != expected_q || r_a != expected_r) begin
|
||||
$display ("Mismatch on unit A at time %d : %d %d vs %d %d",
|
||||
$time,q_a,r_a,expected_q,expected_r);
|
||||
fail = 1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge ready_b)
|
||||
begin
|
||||
#10
|
||||
if (q_b != expected_q || r_b != expected_r) begin
|
||||
$display ("Mismatch on unit B at time %d : %d %d vs %d %d",
|
||||
$time,q_b,r_b,expected_q,expected_r);
|
||||
fail = 1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
151
Advanced Synthesis Cookbook/arithmetic/double_addsub.v
Normal file
151
Advanced Synthesis Cookbook/arithmetic/double_addsub.v
Normal file
@ -0,0 +1,151 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 02-09-06
|
||||
//
|
||||
// This computes the sum of +/- A and +/- B in a single ternary adder chain.
|
||||
// -A is equivalent to ~A + 1 (2's complement)
|
||||
// This can be implemented in Stratix II hardware using a ternary adder
|
||||
// where two channels handle the positive or inverted data and the third
|
||||
// adjusts for 0,1,or 2 +1's
|
||||
//
|
||||
// A and B are treated as unsigned, output is signed 2's comp
|
||||
//
|
||||
|
||||
module double_addsub (a,b,negate_a,negate_b,sum);
|
||||
|
||||
parameter WIDTH = 8;
|
||||
parameter HW_CELLS = 1'b1;
|
||||
|
||||
input [WIDTH-1:0] a;
|
||||
input [WIDTH-1:0] b;
|
||||
input negate_a, negate_b;
|
||||
|
||||
output [WIDTH+1:0] sum;
|
||||
wire [WIDTH+1:0] sum;
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
|
||||
if (HW_CELLS) begin
|
||||
|
||||
wire [WIDTH+1:0] cin,sin;
|
||||
|
||||
assign cin[0] = 1'b0;
|
||||
assign sin[0] = 1'b0;
|
||||
for (i=0; i<WIDTH; i=i+1)
|
||||
begin : das
|
||||
stratixii_lcell_comb w (
|
||||
.dataa(negate_b),
|
||||
.datab(negate_a),
|
||||
.datac(b[i]),
|
||||
.datad(a[i]),
|
||||
|
||||
// unused
|
||||
.datae(1'b0),
|
||||
.dataf(1'b0),
|
||||
.datag(1'b0),
|
||||
|
||||
.cin(cin[i]),
|
||||
.sharein(sin[i]),
|
||||
.sumout(sum[i]),
|
||||
.cout(cin[i+1]),
|
||||
.combout(),
|
||||
.shareout(sin[i+1])
|
||||
);
|
||||
|
||||
defparam w .shared_arith = "on";
|
||||
defparam w .extended_lut = "off";
|
||||
defparam w .lut_mask =
|
||||
i == 0 ? 64'h0000724e00000ff0 :
|
||||
i == 1 ? 64'h00001ac80000e11e :
|
||||
64'h0000124800006996;
|
||||
end
|
||||
|
||||
stratixii_lcell_comb t0 (
|
||||
.dataa(negate_b),
|
||||
.datab(negate_a),
|
||||
.datac(1'b0),
|
||||
.datad(1'b0),
|
||||
|
||||
// unused
|
||||
.datae(1'b0),
|
||||
.dataf(1'b0),
|
||||
.datag(1'b0),
|
||||
|
||||
.cin(cin[WIDTH]),
|
||||
.sharein(sin[WIDTH]),
|
||||
.sumout(sum[WIDTH]),
|
||||
.cout(cin[WIDTH+1]),
|
||||
.combout(),
|
||||
.shareout(sin[WIDTH+1])
|
||||
);
|
||||
|
||||
defparam t0 .shared_arith = "on";
|
||||
defparam t0 .extended_lut = "off";
|
||||
defparam t0 .lut_mask = 64'h0000124800006996;
|
||||
|
||||
stratixii_lcell_comb t1 (
|
||||
.dataa(negate_b),
|
||||
.datab(negate_a),
|
||||
.datac(1'b0),
|
||||
.datad(1'b0),
|
||||
|
||||
// unused
|
||||
.datae(1'b0),
|
||||
.dataf(1'b0),
|
||||
.datag(1'b0),
|
||||
|
||||
.cin(cin[WIDTH+1]),
|
||||
.sharein(sin[WIDTH+1]),
|
||||
.sumout(sum[WIDTH+1]),
|
||||
.cout(),
|
||||
.combout(),
|
||||
.shareout()
|
||||
);
|
||||
|
||||
defparam t1 .shared_arith = "on";
|
||||
defparam t1 .extended_lut = "off";
|
||||
defparam t1 .lut_mask = 64'h0000124800006996;
|
||||
|
||||
end
|
||||
|
||||
else begin
|
||||
|
||||
wire [WIDTH+3:0] tmp_sum;
|
||||
reg [WIDTH+1:0] tmp_c;
|
||||
|
||||
always @(negate_a or negate_b) begin
|
||||
tmp_c = 0;
|
||||
tmp_c [1:0] = {negate_a & negate_b, negate_a ^ negate_b};
|
||||
end
|
||||
|
||||
ternary_add t ( .a( {negate_a,negate_a, a ^ {WIDTH{negate_a}}} ),
|
||||
.b( {negate_b,negate_b, b ^ {WIDTH{negate_b}}} ),
|
||||
.c( tmp_c ),
|
||||
.o( tmp_sum ) );
|
||||
defparam t .WIDTH = WIDTH+2;
|
||||
assign sum = tmp_sum[WIDTH+1:0];
|
||||
end
|
||||
|
||||
endgenerate
|
||||
endmodule
|
70
Advanced Synthesis Cookbook/arithmetic/double_addsub_tb.v
Normal file
70
Advanced Synthesis Cookbook/arithmetic/double_addsub_tb.v
Normal file
@ -0,0 +1,70 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module double_addsub_tb ();
|
||||
|
||||
parameter WIDTH = 10;
|
||||
|
||||
reg [WIDTH-1:0] a,b;
|
||||
wire [WIDTH+1:0] sum_x,sum_y,sum_z;
|
||||
reg negate_a,negate_b,fail;
|
||||
|
||||
double_addsub x (.a(a),.b(b),.negate_a(negate_a),.negate_b(negate_b),.sum(sum_x));
|
||||
defparam x .WIDTH = WIDTH;
|
||||
defparam x .HW_CELLS = 1'b0;
|
||||
|
||||
double_addsub y (.a(a),.b(b),.negate_a(negate_a),.negate_b(negate_b),.sum(sum_y));
|
||||
defparam y .WIDTH = WIDTH;
|
||||
defparam y .HW_CELLS = 1'b1;
|
||||
|
||||
assign sum_z = (negate_a ? -a : a) + (negate_b ? -b : b);
|
||||
|
||||
initial begin
|
||||
a = ~0;
|
||||
b = ~0;
|
||||
negate_a = 0;
|
||||
negate_b = 0;
|
||||
fail = 0;
|
||||
$random(123);
|
||||
end
|
||||
|
||||
always begin
|
||||
#1000
|
||||
a = $random;
|
||||
b = $random;
|
||||
negate_a = $random;
|
||||
negate_b = $random;
|
||||
|
||||
#1000
|
||||
if (sum_x != sum_z || sum_y != sum_z) begin
|
||||
$display ("Mismatch at time %d",$time);
|
||||
fail = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
initial begin
|
||||
#1000000
|
||||
if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
endmodule
|
43
Advanced Synthesis Cookbook/arithmetic/iter_addsub.v
Normal file
43
Advanced Synthesis Cookbook/arithmetic/iter_addsub.v
Normal file
@ -0,0 +1,43 @@
|
||||
// Copyright 2008 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module iter_addsub (
|
||||
input clk,sclr,
|
||||
input first,sub,
|
||||
input a,b,
|
||||
output sum
|
||||
);
|
||||
|
||||
reg car;
|
||||
assign sum = a ^ (sub ^ b) ^ (first ? sub : car);
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (sclr) car <= 1'b0;
|
||||
else car <= a & (sub ^ b) |
|
||||
a & (first ? sub : car) |
|
||||
(sub ^ b) & (first ? sub : car);
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
147
Advanced Synthesis Cookbook/arithmetic/karatsuba_mult.v
Normal file
147
Advanced Synthesis Cookbook/arithmetic/karatsuba_mult.v
Normal file
@ -0,0 +1,147 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler, liu - 06-14-2007
|
||||
|
||||
module karatsuba_mult (clk, a, b, o);
|
||||
|
||||
parameter IN_WIDTH = 64; // must be even
|
||||
localparam OUT_WIDTH = 2*IN_WIDTH;
|
||||
localparam WORD_WIDTH = IN_WIDTH / 2;
|
||||
|
||||
input [IN_WIDTH-1:0] a, b;
|
||||
input clk;
|
||||
output [OUT_WIDTH-1:0] o;
|
||||
|
||||
wire [WORD_WIDTH-1:0] a_h, a_l, b_h, b_l;
|
||||
assign {a_h,a_l} = a;
|
||||
assign {b_h,b_l} = b;
|
||||
|
||||
// tick 0 - Input registers
|
||||
reg [WORD_WIDTH-1:0] a_hr,a_lr,b_hr,b_lr;
|
||||
always @(posedge clk) begin
|
||||
a_hr <= a_h;
|
||||
a_lr <= a_l;
|
||||
b_hr <= b_h;
|
||||
b_lr <= b_l;
|
||||
end
|
||||
|
||||
wire [WORD_WIDTH:0] a_hl, b_hl;
|
||||
assign a_hl = a_hr + a_lr;
|
||||
assign b_hl = b_hr + b_lr;
|
||||
|
||||
// ticks 0 1 2
|
||||
wire [IN_WIDTH-1:0] pphh, ppll;
|
||||
mult_3tick mx (.clk(clk),.a_in(a_h),.b_in(b_h),.o(pphh));
|
||||
defparam mx .IN_WIDTH = WORD_WIDTH;
|
||||
mult_3tick my (.clk(clk),.a_in(a_l),.b_in(b_l),.o(ppll));
|
||||
defparam my .IN_WIDTH = WORD_WIDTH;
|
||||
|
||||
// ticks 1 2 3
|
||||
wire [IN_WIDTH+1:0] pphl;
|
||||
mult_3tick mz (.clk(clk),.a_in(a_hl),.b_in(b_hl),.o(pphl));
|
||||
defparam mz .IN_WIDTH = WORD_WIDTH+1;
|
||||
|
||||
// desired function is Out =
|
||||
// {pphh,ppll} - pphh<<WORD_WIDTH - ppll<<WORD_WIDTH + pphl<<WORD_WIDTH
|
||||
|
||||
reg [WORD_WIDTH-2:0] o_h_quarter_reg3;
|
||||
reg [WORD_WIDTH-1:0] o_l_quarter_reg3;
|
||||
wire [IN_WIDTH:0] comp_a_oo, comp_a_ot;
|
||||
reg [IN_WIDTH:0] comp_a_oo_r, comp_a_ot_r;
|
||||
|
||||
// the low order 1's dispose of the first two's comp
|
||||
// +1 - net effect is (+1 << WORD_WIDTH)
|
||||
compress_32 comp_a (
|
||||
.a({pphh[WORD_WIDTH-1:0],ppll[IN_WIDTH-1:WORD_WIDTH]}),
|
||||
.b(~pphh),
|
||||
.c(~ppll),
|
||||
.oo(comp_a_oo[IN_WIDTH-1:0]),
|
||||
.ot(comp_a_ot[IN_WIDTH:1])
|
||||
);
|
||||
defparam comp_a .WIDTH = IN_WIDTH;
|
||||
|
||||
assign comp_a_oo[IN_WIDTH] = pphh[WORD_WIDTH];
|
||||
assign comp_a_ot[0] = 1'b1;
|
||||
|
||||
// tick 3
|
||||
always @(posedge clk) begin
|
||||
o_h_quarter_reg3 <= pphh[IN_WIDTH-1:WORD_WIDTH+1];
|
||||
o_l_quarter_reg3 <= ppll[WORD_WIDTH-1:0];
|
||||
comp_a_oo_r <= comp_a_oo;
|
||||
comp_a_ot_r <= comp_a_ot;
|
||||
end
|
||||
|
||||
wire [IN_WIDTH+1:0] comp_b_oo, comp_b_ot;
|
||||
|
||||
compress_32 comp_b (
|
||||
.a(comp_a_oo_r),
|
||||
.b(comp_a_ot_r),
|
||||
.c(pphl[IN_WIDTH:0]),
|
||||
.oo(comp_b_oo[IN_WIDTH:0]),
|
||||
.ot(comp_b_ot[IN_WIDTH+1:1])
|
||||
);
|
||||
defparam comp_b .WIDTH = IN_WIDTH+1;
|
||||
|
||||
assign comp_b_oo[IN_WIDTH+1] = ~pphl[IN_WIDTH+1];
|
||||
assign comp_b_ot[0] = 1'b1;
|
||||
|
||||
// ticks 4 and 5
|
||||
reg [WORD_WIDTH-2:0] o_h_quarter_reg4;
|
||||
wire [WORD_WIDTH-2:0] o_h_quarter_reg4_plus /*synthesis keep*/;
|
||||
reg [WORD_WIDTH-1:0] o_l_quarter_reg4;
|
||||
reg [WORD_WIDTH-2:0] o_h_quarter_reg5;
|
||||
reg [WORD_WIDTH-1:0] o_l_quarter_reg5;
|
||||
|
||||
wire o_h_sel;
|
||||
wire tmp;
|
||||
|
||||
// this is a 2 cycle pipelined adder modified to expose the
|
||||
// unregistered most significant bit.
|
||||
|
||||
pipeline_add_msb pa (
|
||||
.clk(clk),
|
||||
.rst(1'b0),
|
||||
.a(comp_b_oo),
|
||||
.b(comp_b_ot),
|
||||
.o({tmp, o[IN_WIDTH+WORD_WIDTH:WORD_WIDTH]}),
|
||||
.msb(o_h_sel)
|
||||
);
|
||||
defparam pa .LS_WIDTH = WORD_WIDTH+1;
|
||||
defparam pa .MS_WIDTH = WORD_WIDTH+1;
|
||||
|
||||
assign o_h_quarter_reg4_plus = o_h_quarter_reg4 + 1;
|
||||
|
||||
always @(posedge clk) begin
|
||||
o_h_quarter_reg4 <= o_h_quarter_reg3;
|
||||
|
||||
// carry select speed optimization
|
||||
o_h_quarter_reg5 <= o_h_sel? o_h_quarter_reg4_plus : o_h_quarter_reg4;
|
||||
|
||||
o_l_quarter_reg4 <= o_l_quarter_reg3;
|
||||
o_l_quarter_reg5 <= o_l_quarter_reg4;
|
||||
end
|
||||
|
||||
assign o[WORD_WIDTH-1:0] = o_l_quarter_reg5;
|
||||
assign o[OUT_WIDTH-1:IN_WIDTH+WORD_WIDTH+1] = o_h_quarter_reg5;
|
||||
|
||||
endmodule
|
84
Advanced Synthesis Cookbook/arithmetic/karatsuba_mult_tb.v
Normal file
84
Advanced Synthesis Cookbook/arithmetic/karatsuba_mult_tb.v
Normal file
@ -0,0 +1,84 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module karatsuba_mult_tb ();
|
||||
|
||||
parameter IN_WIDTH = 32; // smaller width for testing. 64x64 nominal
|
||||
|
||||
reg clk = 0;
|
||||
|
||||
reg [IN_WIDTH-1:0] a,b;
|
||||
wire [2*IN_WIDTH-1:0] o;
|
||||
|
||||
////////////////////////////////
|
||||
// DUT
|
||||
////////////////////////////////
|
||||
|
||||
karatsuba_mult km (
|
||||
.clk(clk),
|
||||
.a(a),
|
||||
.b(b),
|
||||
.o(o)
|
||||
);
|
||||
defparam km .IN_WIDTH = IN_WIDTH;
|
||||
|
||||
////////////////////////////////
|
||||
// functional model
|
||||
////////////////////////////////
|
||||
parameter LATENCY = 6;
|
||||
reg [LATENCY * 2*IN_WIDTH-1:0] m;
|
||||
wire [2*IN_WIDTH-1:0] o2 = m[LATENCY*2*IN_WIDTH-1:(LATENCY-1)*2*IN_WIDTH];
|
||||
|
||||
always @(posedge clk) begin
|
||||
m <= (m << 2*IN_WIDTH) | (a * b);
|
||||
end
|
||||
|
||||
////////////////////////////////
|
||||
// test stimulus + check
|
||||
////////////////////////////////
|
||||
|
||||
always @(negedge clk) begin
|
||||
a = $random;
|
||||
b = $random;
|
||||
end
|
||||
|
||||
reg fail = 0;
|
||||
|
||||
integer cyc = 0;
|
||||
always @(posedge clk) begin
|
||||
cyc <= cyc + 1'b1;
|
||||
#2 if ((o2 !== o) && (cyc > LATENCY)) begin
|
||||
$display ("Mismatch at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
end
|
||||
|
||||
initial begin
|
||||
#1000000 if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
always begin
|
||||
#100 clk = ~clk;
|
||||
end
|
||||
|
||||
endmodule
|
161
Advanced Synthesis Cookbook/arithmetic/lc_mult_signed.v
Normal file
161
Advanced Synthesis Cookbook/arithmetic/lc_mult_signed.v
Normal file
@ -0,0 +1,161 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler -01-02-2007
|
||||
module lc_mult_signed (clk,a,b,o);
|
||||
|
||||
parameter WIDTH_A = 16;
|
||||
parameter WIDTH_B = 13;
|
||||
parameter WIDTH_O = WIDTH_A + WIDTH_B;
|
||||
parameter REGISTER_LAYERS = 1;
|
||||
parameter REGISTER_MIDPOINTS = 1;
|
||||
|
||||
/////////////////////////////////////
|
||||
// these are just for sanity - to
|
||||
// display the actual latency in
|
||||
// simulation.
|
||||
/////////////////////////////////////
|
||||
function integer layer_latency;
|
||||
input integer words;
|
||||
begin
|
||||
layer_latency = 2;
|
||||
while (words > 1) begin
|
||||
words = (words/2) + (words - (2*(words/2)));
|
||||
layer_latency = layer_latency + 1;
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
function integer midpoint_latency;
|
||||
input integer words;
|
||||
begin
|
||||
midpoint_latency = 0;
|
||||
while (words > 1) begin
|
||||
words = (words/2) + (words - (2*(words/2)));
|
||||
midpoint_latency = midpoint_latency + 1;
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
input clk;
|
||||
input [WIDTH_A-1:0] a;
|
||||
input [WIDTH_B-1:0] b;
|
||||
output [WIDTH_O-1:0] o;
|
||||
|
||||
wire b_negative = b[WIDTH_B-1];
|
||||
wire [WIDTH_O-1:0] o_wire;
|
||||
reg [WIDTH_O-1:0] o;
|
||||
|
||||
genvar i;
|
||||
wire [WIDTH_B * WIDTH_A - 1:0] partials;
|
||||
|
||||
// report the latency in simulation
|
||||
generate
|
||||
if (REGISTER_LAYERS) begin
|
||||
initial begin
|
||||
$display ("lc_mult_signed layer latency for WIDTH_B=%d is %d",
|
||||
WIDTH_B,layer_latency(WIDTH_B));
|
||||
end
|
||||
end
|
||||
if (REGISTER_MIDPOINTS) begin
|
||||
initial begin
|
||||
$display ("lc_mult_signed midpoint latency for WIDTH_B=%d is %d",
|
||||
WIDTH_B,midpoint_latency(WIDTH_B));
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
/////////////////////////////////////
|
||||
// Construct the partial products
|
||||
/////////////////////////////////////
|
||||
|
||||
// for all but the last word do simple AND gates
|
||||
generate
|
||||
for (i=0; i<(WIDTH_B-1); i=i+1)
|
||||
begin : ps
|
||||
assign partials[i*WIDTH_A+WIDTH_A-1:i*WIDTH_A] = a & {WIDTH_A{b[i]}};
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// for the last word and with !A
|
||||
// this is analagous to B and (B xor A)
|
||||
assign partials[WIDTH_B*WIDTH_A-1:WIDTH_B*WIDTH_A-WIDTH_A] = ~a & {WIDTH_A{b[WIDTH_B-1]}};
|
||||
|
||||
reg [WIDTH_B * WIDTH_A - 1:0] partials_r;
|
||||
reg b_negative_r;
|
||||
generate
|
||||
if (REGISTER_LAYERS) begin
|
||||
always @(posedge clk) begin
|
||||
partials_r <= partials;
|
||||
b_negative_r <= b_negative;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
always @(*) begin
|
||||
partials_r = partials;
|
||||
b_negative_r <= b_negative;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
/////////////////////////////////////
|
||||
// Sum the partial products
|
||||
/////////////////////////////////////
|
||||
wire [WIDTH_O-1:0] sum;
|
||||
wire b_negative_final;
|
||||
adder_tree at (.clk(clk),
|
||||
.in_words(partials_r),
|
||||
.extra_bit_in(b_negative_r),
|
||||
.extra_bit_out(b_negative_final),
|
||||
.out(sum));
|
||||
defparam at .NUM_IN_WORDS = WIDTH_B;
|
||||
defparam at .BITS_PER_IN_WORD = WIDTH_A;
|
||||
defparam at .OUT_BITS = WIDTH_O;
|
||||
defparam at .SIGN_EXT = 1;
|
||||
defparam at .REGISTER_OUTPUT = REGISTER_LAYERS;
|
||||
defparam at .REGISTER_MIDDLE = REGISTER_MIDPOINTS;
|
||||
defparam at .SHIFT_DIST = 1;
|
||||
defparam at .EXTRA_BIT_USED = 1;
|
||||
|
||||
/////////////////////////////////////
|
||||
// final signed correction
|
||||
/////////////////////////////////////
|
||||
assign o_wire = sum + (b_negative_final << (WIDTH_B-1));
|
||||
|
||||
/////////////////////////////////////
|
||||
// optional output registers
|
||||
/////////////////////////////////////
|
||||
generate
|
||||
if (REGISTER_LAYERS) begin
|
||||
always @(posedge clk) begin
|
||||
o <= o_wire;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
always @(*) begin
|
||||
o = o_wire;
|
||||
end
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
135
Advanced Synthesis Cookbook/arithmetic/lc_mult_signed_tb.v
Normal file
135
Advanced Synthesis Cookbook/arithmetic/lc_mult_signed_tb.v
Normal file
@ -0,0 +1,135 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 01-03-2006
|
||||
|
||||
module lc_mult_signed_tb ();
|
||||
|
||||
parameter WIDTH_A = 16;
|
||||
parameter WIDTH_B = 13;
|
||||
parameter WIDTH_O = WIDTH_A + WIDTH_B;
|
||||
parameter LATENCY_L = 6;
|
||||
parameter LATENCY_LM = 10;
|
||||
|
||||
reg clk;
|
||||
|
||||
//////////////////////////////////
|
||||
// unit under test - no pipeline
|
||||
//////////////////////////////////
|
||||
reg [WIDTH_A-1:0] a;
|
||||
reg [WIDTH_B-1:0] b;
|
||||
wire [WIDTH_O-1:0] o;
|
||||
lc_mult_signed m (.clk(clk),.a(a),.b(b),.o(o));
|
||||
defparam m .WIDTH_A = WIDTH_A;
|
||||
defparam m .WIDTH_B = WIDTH_B;
|
||||
defparam m .WIDTH_O = WIDTH_O;
|
||||
defparam m .REGISTER_LAYERS = 0;
|
||||
defparam m .REGISTER_MIDPOINTS = 0;
|
||||
|
||||
//////////////////////////////////
|
||||
// unit under test - layer pipelined
|
||||
//////////////////////////////////
|
||||
wire [WIDTH_O-1:0] op;
|
||||
lc_mult_signed mp (.clk(clk),.a(a),.b(b),.o(op));
|
||||
defparam mp .WIDTH_A = WIDTH_A;
|
||||
defparam mp .WIDTH_B = WIDTH_B;
|
||||
defparam mp .WIDTH_O = WIDTH_O;
|
||||
defparam mp .REGISTER_LAYERS = 1;
|
||||
defparam mp .REGISTER_MIDPOINTS = 0;
|
||||
|
||||
//////////////////////////////////
|
||||
// unit under test - layer and middle pipelined
|
||||
//////////////////////////////////
|
||||
wire [WIDTH_O-1:0] opp;
|
||||
lc_mult_signed mpp (.clk(clk),.a(a),.b(b),.o(opp));
|
||||
defparam mpp .WIDTH_A = WIDTH_A;
|
||||
defparam mpp .WIDTH_B = WIDTH_B;
|
||||
defparam mpp .WIDTH_O = WIDTH_O;
|
||||
defparam mpp .REGISTER_LAYERS = 1;
|
||||
defparam mpp .REGISTER_MIDPOINTS = 1;
|
||||
|
||||
/////////////////////
|
||||
// reference unit
|
||||
/////////////////////
|
||||
wire signed [WIDTH_A-1:0] as;
|
||||
wire signed [WIDTH_B-1:0] bs;
|
||||
wire signed [WIDTH_O-1:0] os;
|
||||
assign as = a;
|
||||
assign bs = b;
|
||||
assign os = as * bs;
|
||||
|
||||
////////////////////////////////
|
||||
// history for reference unit
|
||||
////////////////////////////////
|
||||
reg [WIDTH_O*LATENCY_LM-1:0] pipe_history;
|
||||
reg [LATENCY_LM-1:0] pipe_flushed;
|
||||
wire [WIDTH_O-1:0] osp,ospp;
|
||||
initial begin
|
||||
pipe_history = 0;
|
||||
pipe_flushed = 0;
|
||||
end
|
||||
always @(posedge clk) begin
|
||||
pipe_history <= (pipe_history << WIDTH_O) | os;
|
||||
pipe_flushed <= (pipe_flushed << 1) | 1'b1;
|
||||
end
|
||||
assign osp = pipe_history[WIDTH_O*LATENCY_L-1:WIDTH_O*LATENCY_L-WIDTH_O];
|
||||
assign ospp = pipe_history[WIDTH_O*LATENCY_LM-1:WIDTH_O*LATENCY_LM-WIDTH_O];
|
||||
|
||||
/////////////////////
|
||||
// stim
|
||||
/////////////////////
|
||||
reg fail;
|
||||
initial begin
|
||||
a = 0;
|
||||
b = 0;
|
||||
clk = 0;
|
||||
fail = 0;
|
||||
#1000000
|
||||
if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
always @(negedge clk) begin
|
||||
a = $random;
|
||||
b = $random;
|
||||
end
|
||||
|
||||
always begin
|
||||
#100 clk = ~clk;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
#10 if (os !== o) begin
|
||||
$display ("Mismatch in unregistered unit at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
if (&pipe_flushed && (osp !== op)) begin
|
||||
$display ("Mismatch in layer pipelined unit at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
if (&pipe_flushed && (ospp !== opp)) begin
|
||||
$display ("Mismatch in layer and midpoint pipelined unit at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
41
Advanced Synthesis Cookbook/arithmetic/log2.inc
Normal file
41
Advanced Synthesis Cookbook/arithmetic/log2.inc
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 12-12-2006
|
||||
// helper function to compute LOG base 2
|
||||
//
|
||||
// NOTE - This is a somewhat abusive definition of LOG2(v) as the
|
||||
// number of bits required to represent "v". So log2(256) will be
|
||||
// 9 rather than 8 (256 = 9'b1_0000_0000). I apologize for any
|
||||
// confusion this may cause.
|
||||
//
|
||||
|
||||
function integer log2;
|
||||
input integer val;
|
||||
begin
|
||||
log2 = 0;
|
||||
while (val > 0) begin
|
||||
val = val >> 1;
|
||||
log2 = log2 + 1;
|
||||
end
|
||||
end
|
||||
endfunction
|
48
Advanced Synthesis Cookbook/arithmetic/make_comp.cpp
Normal file
48
Advanced Synthesis Cookbook/arithmetic/make_comp.cpp
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int const num_ins = 3;
|
||||
|
||||
int main (void)
|
||||
{
|
||||
unsigned int n = 0, k = 0, sum = 0;
|
||||
|
||||
fprintf (stdout," case (data)\n");
|
||||
for (n=0; n<(1<<num_ins); n++)
|
||||
{
|
||||
sum = 0;
|
||||
for (k=0; k<num_ins; k++)
|
||||
{
|
||||
if ((n & (1 << k)) != 0)
|
||||
{
|
||||
sum++;
|
||||
}
|
||||
}
|
||||
fprintf (stdout," %d: sum=%d;\n",n,sum);
|
||||
}
|
||||
fprintf (stdout," default: sum=0;\n");
|
||||
fprintf (stdout," endcase\n");
|
||||
|
||||
return (0);
|
||||
}
|
45
Advanced Synthesis Cookbook/arithmetic/make_sum.cpp
Normal file
45
Advanced Synthesis Cookbook/arithmetic/make_sum.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright 2008 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int const num_ins = 3; // per word to add
|
||||
int const num_outs = num_ins + 1;
|
||||
|
||||
int main (void)
|
||||
{
|
||||
unsigned int n = 0, k = 0, sum = 0;
|
||||
unsigned int mask = (1 << num_ins) - 1;
|
||||
|
||||
fprintf (stdout," case (data)\n");
|
||||
for (n=0; n<(1<<(num_ins*2)); n++)
|
||||
{
|
||||
sum = (n >> num_ins) & mask;
|
||||
sum += (n & mask);
|
||||
|
||||
fprintf (stdout," %d'd%d: sum=%d'd%d;\n",2*num_ins,n,num_outs,sum);
|
||||
}
|
||||
fprintf (stdout," default: sum=0;\n");
|
||||
fprintf (stdout," endcase\n");
|
||||
|
||||
return (0);
|
||||
}
|
396
Advanced Synthesis Cookbook/arithmetic/mult_3tick.v
Normal file
396
Advanced Synthesis Cookbook/arithmetic/mult_3tick.v
Normal file
@ -0,0 +1,396 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 06-11-2007
|
||||
|
||||
// Latency 3 pipelined DSP block based multiplier.
|
||||
// input width up to 36x36 with input, output, and pipeline registers.
|
||||
//
|
||||
// This was derived from a pipelined LPM MULT VQM.
|
||||
// The awkward flow is necessary to be super explicit about
|
||||
// where the registers are intended to be. The tools
|
||||
// are too clever for their own good sometimes.
|
||||
//
|
||||
|
||||
module mult_3tick (
|
||||
clk,
|
||||
a_in,
|
||||
b_in,
|
||||
o
|
||||
);
|
||||
|
||||
parameter IN_WIDTH = 36;
|
||||
parameter OUT_WIDTH = 2 * IN_WIDTH;
|
||||
|
||||
input clk;
|
||||
input [IN_WIDTH-1:0] a_in, b_in;
|
||||
output [OUT_WIDTH-1:0] o;
|
||||
|
||||
// ENHANCEMENT - shift these left
|
||||
wire [35:0] a = 36'b0 | a_in;
|
||||
wire [35:0] b = 36'b0 | b_in;
|
||||
wire [71:0] o_int;
|
||||
assign o = o_int[OUT_WIDTH-1:0];
|
||||
|
||||
wire gnd;
|
||||
wire vcc;
|
||||
assign gnd = 1'b0;
|
||||
assign vcc = 1'b1;
|
||||
|
||||
wire [35:0] mult1_out;
|
||||
stratixii_mac_mult mult1_i (
|
||||
.signa(gnd),
|
||||
.signb(gnd),
|
||||
.sourcea(gnd),
|
||||
.sourceb(gnd),
|
||||
.round(gnd),
|
||||
.saturate(gnd),
|
||||
.dataa({a[17:0]}),
|
||||
.datab({b[17:0]}),
|
||||
.clk({clk_unconnected_wire_0,clk_unconnected_wire_1,clk_unconnected_wire_2,clk}),
|
||||
.aclr({gnd,gnd,gnd,gnd}),
|
||||
.ena({vcc,vcc,vcc,vcc}),
|
||||
|
||||
.scanina(18'b0),
|
||||
.scaninb(18'b0),
|
||||
.scanouta(),
|
||||
.scanoutb(),
|
||||
|
||||
// synthesis translate off
|
||||
// simulation only ports
|
||||
.devpor(1'b1),
|
||||
.devclrn(1'b1),
|
||||
.zeroacc(1'b0),
|
||||
.mode(1'b0),
|
||||
// synthesis translate on
|
||||
|
||||
.dataout(mult1_out[35:0])
|
||||
// .observabledataa_regout(),
|
||||
// .observabledatab_regout());
|
||||
);
|
||||
|
||||
defparam mult1_i .dataa_width = 18;
|
||||
defparam mult1_i .datab_width = 18;
|
||||
defparam mult1_i .dataa_clock = "0";
|
||||
defparam mult1_i .datab_clock = "0";
|
||||
defparam mult1_i .signa_clock = "none";
|
||||
defparam mult1_i .signb_clock = "none";
|
||||
defparam mult1_i .dataa_clear = "0";
|
||||
defparam mult1_i .datab_clear = "0";
|
||||
defparam mult1_i .signa_clear = "none";
|
||||
defparam mult1_i .signb_clear = "none";
|
||||
defparam mult1_i .output_clock = "0";
|
||||
defparam mult1_i .output_clear = "0";
|
||||
defparam mult1_i .round_clock = "none";
|
||||
defparam mult1_i .round_clear = "none";
|
||||
defparam mult1_i .saturate_clock = "none";
|
||||
defparam mult1_i .saturate_clear = "none";
|
||||
defparam mult1_i .mode_clock = "none";
|
||||
defparam mult1_i .zeroacc_clock = "none";
|
||||
defparam mult1_i .mode_clear = "none";
|
||||
defparam mult1_i .zeroacc_clear = "none";
|
||||
defparam mult1_i .dynamic_mode = "no";
|
||||
defparam mult1_i .bypass_multiplier = "no";
|
||||
defparam mult1_i .signa_internally_grounded = "true";
|
||||
defparam mult1_i .signb_internally_grounded = "true";
|
||||
|
||||
wire [35:0] mult2_out;
|
||||
stratixii_mac_mult mult2_i (
|
||||
.signa(gnd),
|
||||
.signb(gnd),
|
||||
.sourcea(gnd),
|
||||
.sourceb(gnd),
|
||||
.round(gnd),
|
||||
.saturate(gnd),
|
||||
.dataa(a[35:18]),
|
||||
.datab(b[35:18]),
|
||||
.clk({clk_unconnected_wire_3,clk_unconnected_wire_4,clk_unconnected_wire_5,clk}),
|
||||
.aclr({gnd,gnd,gnd,gnd}),
|
||||
.ena({vcc,vcc,vcc,vcc}),
|
||||
|
||||
.scanina(18'b0),
|
||||
.scaninb(18'b0),
|
||||
.scanouta(),
|
||||
.scanoutb(),
|
||||
|
||||
// synthesis translate off
|
||||
// simulation only ports
|
||||
.devpor(1'b1),
|
||||
.devclrn(1'b1),
|
||||
.zeroacc(1'b0),
|
||||
.mode(1'b0),
|
||||
// synthesis translate on
|
||||
|
||||
.dataout(mult2_out[35:0])
|
||||
// .observabledataa_regout(),
|
||||
// .observabledatab_regout());
|
||||
);
|
||||
defparam mult2_i .dataa_width = 18;
|
||||
defparam mult2_i .datab_width = 18;
|
||||
defparam mult2_i .dataa_clock = "0";
|
||||
defparam mult2_i .datab_clock = "0";
|
||||
defparam mult2_i .signa_clock = "none";
|
||||
defparam mult2_i .signb_clock = "none";
|
||||
defparam mult2_i .dataa_clear = "0";
|
||||
defparam mult2_i .datab_clear = "0";
|
||||
defparam mult2_i .signa_clear = "none";
|
||||
defparam mult2_i .signb_clear = "none";
|
||||
defparam mult2_i .output_clock = "0";
|
||||
defparam mult2_i .output_clear = "0";
|
||||
defparam mult2_i .round_clock = "none";
|
||||
defparam mult2_i .round_clear = "none";
|
||||
defparam mult2_i .saturate_clock = "none";
|
||||
defparam mult2_i .saturate_clear = "none";
|
||||
defparam mult2_i .mode_clock = "none";
|
||||
defparam mult2_i .zeroacc_clock = "none";
|
||||
defparam mult2_i .mode_clear = "none";
|
||||
defparam mult2_i .zeroacc_clear = "none";
|
||||
defparam mult2_i .dynamic_mode = "no";
|
||||
defparam mult2_i .bypass_multiplier = "no";
|
||||
defparam mult2_i .signa_internally_grounded = "false";
|
||||
defparam mult2_i .signb_internally_grounded = "false";
|
||||
|
||||
wire [35:0] mult3_out;
|
||||
stratixii_mac_mult mult3_i (
|
||||
.signa(gnd),
|
||||
.signb(gnd),
|
||||
.sourcea(gnd),
|
||||
.sourceb(gnd),
|
||||
.round(gnd),
|
||||
.saturate(gnd),
|
||||
.dataa(a[35:18]),
|
||||
.datab(b[17:0]),
|
||||
.clk({clk_unconnected_wire_6,clk_unconnected_wire_7,clk_unconnected_wire_8,clk}),
|
||||
.aclr({gnd,gnd,gnd,gnd}),
|
||||
.ena({vcc,vcc,vcc,vcc}),
|
||||
|
||||
.scanina(18'b0),
|
||||
.scaninb(18'b0),
|
||||
.scanouta(),
|
||||
.scanoutb(),
|
||||
|
||||
// synthesis translate off
|
||||
// simulation only ports
|
||||
.devpor(1'b1),
|
||||
.devclrn(1'b1),
|
||||
.zeroacc(1'b0),
|
||||
.mode(1'b0),
|
||||
// synthesis translate on
|
||||
|
||||
.dataout(mult3_out[35:0])
|
||||
// .observabledataa_regout(),
|
||||
// .observabledatab_regout());
|
||||
);
|
||||
defparam mult3_i .dataa_width = 18;
|
||||
defparam mult3_i .datab_width = 18;
|
||||
defparam mult3_i .dataa_clock = "0";
|
||||
defparam mult3_i .datab_clock = "0";
|
||||
defparam mult3_i .signa_clock = "none";
|
||||
defparam mult3_i .signb_clock = "none";
|
||||
defparam mult3_i .dataa_clear = "0";
|
||||
defparam mult3_i .datab_clear = "0";
|
||||
defparam mult3_i .signa_clear = "none";
|
||||
defparam mult3_i .signb_clear = "none";
|
||||
defparam mult3_i .output_clock = "0";
|
||||
defparam mult3_i .output_clear = "0";
|
||||
defparam mult3_i .round_clock = "none";
|
||||
defparam mult3_i .round_clear = "none";
|
||||
defparam mult3_i .saturate_clock = "none";
|
||||
defparam mult3_i .saturate_clear = "none";
|
||||
defparam mult3_i .mode_clock = "none";
|
||||
defparam mult3_i .zeroacc_clock = "none";
|
||||
defparam mult3_i .mode_clear = "none";
|
||||
defparam mult3_i .zeroacc_clear = "none";
|
||||
defparam mult3_i .dynamic_mode = "no";
|
||||
defparam mult3_i .bypass_multiplier = "no";
|
||||
defparam mult3_i .signa_internally_grounded = "false";
|
||||
defparam mult3_i .signb_internally_grounded = "true";
|
||||
|
||||
wire [35:0] mult4_out;
|
||||
stratixii_mac_mult mult4_i (
|
||||
.signa(gnd),
|
||||
.signb(gnd),
|
||||
.sourcea(gnd),
|
||||
.sourceb(gnd),
|
||||
.round(gnd),
|
||||
.saturate(gnd),
|
||||
.dataa(a[17:0]),
|
||||
.datab(b[35:18]),
|
||||
.clk({clk_unconnected_wire_9,clk_unconnected_wire_10,clk_unconnected_wire_11,clk}),
|
||||
.aclr({gnd,gnd,gnd,gnd}),
|
||||
.ena({vcc,vcc,vcc,vcc}),
|
||||
|
||||
.scanina(18'b0),
|
||||
.scaninb(18'b0),
|
||||
.scanouta(),
|
||||
.scanoutb(),
|
||||
|
||||
// synthesis translate off
|
||||
// simulation only ports
|
||||
.devpor(1'b1),
|
||||
.devclrn(1'b1),
|
||||
.zeroacc(1'b0),
|
||||
.mode(1'b0),
|
||||
// synthesis translate on
|
||||
|
||||
.dataout(mult4_out[35:0])
|
||||
// .observabledataa_regout(),
|
||||
// .observabledatab_regout());
|
||||
);
|
||||
defparam mult4_i .dataa_width = 18;
|
||||
defparam mult4_i .datab_width = 18;
|
||||
defparam mult4_i .dataa_clock = "0";
|
||||
defparam mult4_i .datab_clock = "0";
|
||||
defparam mult4_i .signa_clock = "none";
|
||||
defparam mult4_i .signb_clock = "none";
|
||||
defparam mult4_i .dataa_clear = "0";
|
||||
defparam mult4_i .datab_clear = "0";
|
||||
defparam mult4_i .signa_clear = "none";
|
||||
defparam mult4_i .signb_clear = "none";
|
||||
defparam mult4_i .output_clock = "0";
|
||||
defparam mult4_i .output_clear = "0";
|
||||
defparam mult4_i .round_clock = "none";
|
||||
defparam mult4_i .round_clear = "none";
|
||||
defparam mult4_i .saturate_clock = "none";
|
||||
defparam mult4_i .saturate_clear = "none";
|
||||
defparam mult4_i .mode_clock = "none";
|
||||
defparam mult4_i .zeroacc_clock = "none";
|
||||
defparam mult4_i .mode_clear = "none";
|
||||
defparam mult4_i .zeroacc_clear = "none";
|
||||
defparam mult4_i .dynamic_mode = "no";
|
||||
defparam mult4_i .bypass_multiplier = "no";
|
||||
defparam mult4_i .signa_internally_grounded = "true";
|
||||
defparam mult4_i .signb_internally_grounded = "false";
|
||||
|
||||
stratixii_mac_out out5 (
|
||||
.multabsaturate(gnd),
|
||||
.multcdsaturate(gnd),
|
||||
.signa(gnd),
|
||||
.signb(gnd),
|
||||
.dataa(mult1_out),
|
||||
.datab(mult2_out),
|
||||
.datac(mult3_out),
|
||||
.datad(mult4_out),
|
||||
.clk({clk_unconnected_wire_9,clk_unconnected_wire_10,clk_unconnected_wire_11,clk}),
|
||||
.aclr({gnd,gnd,gnd,gnd}),
|
||||
.ena({vcc,vcc,vcc,vcc}),
|
||||
|
||||
// synthesis translate off
|
||||
// simulation only ports
|
||||
.saturate(1'b0),
|
||||
.saturate1(1'b0),
|
||||
.devpor(1'b1),
|
||||
.devclrn(1'b1),
|
||||
.zeroacc(1'b0),
|
||||
.zeroacc1(1'b0),
|
||||
.mode0(1'b0),
|
||||
.mode1(1'b0),
|
||||
.accoverflow(),
|
||||
// synthesis translate on
|
||||
|
||||
.round0(1'b0),
|
||||
.round1(1'b0),
|
||||
.addnsub0(1'b0),
|
||||
.addnsub1(1'b0),
|
||||
|
||||
.dataout(o_int));
|
||||
defparam out5 .operation_mode = "36_bit_multiply";
|
||||
defparam out5 .dataa_width = 36;
|
||||
defparam out5 .datab_width = 36;
|
||||
defparam out5 .datac_width = 36;
|
||||
defparam out5 .datad_width = 36;
|
||||
defparam out5 .addnsub0_clock = "none";
|
||||
defparam out5 .addnsub1_clock = "none";
|
||||
defparam out5 .addnsub0_pipeline_clock = "none";
|
||||
defparam out5 .addnsub1_pipeline_clock = "none";
|
||||
defparam out5 .addnsub0_clear = "none";
|
||||
defparam out5 .addnsub1_clear = "none";
|
||||
defparam out5 .addnsub0_pipeline_clear = "none";
|
||||
defparam out5 .addnsub1_pipeline_clear = "none";
|
||||
defparam out5 .round0_clock = "none";
|
||||
defparam out5 .round1_clock = "none";
|
||||
defparam out5 .round0_pipeline_clock = "none";
|
||||
defparam out5 .round1_pipeline_clock = "none";
|
||||
defparam out5 .round0_clear = "none";
|
||||
defparam out5 .round1_clear = "none";
|
||||
defparam out5 .round0_pipeline_clear = "none";
|
||||
defparam out5 .round1_pipeline_clear = "none";
|
||||
defparam out5 .saturate_clock = "none";
|
||||
defparam out5 .multabsaturate_clock = "none";
|
||||
defparam out5 .multcdsaturate_clock = "none";
|
||||
defparam out5 .saturate_pipeline_clock = "none";
|
||||
defparam out5 .multabsaturate_pipeline_clock = "none";
|
||||
defparam out5 .multcdsaturate_pipeline_clock = "none";
|
||||
defparam out5 .saturate_clear = "none";
|
||||
defparam out5 .multabsaturate_clear = "none";
|
||||
defparam out5 .multcdsaturate_clear = "none";
|
||||
defparam out5 .saturate_pipeline_clear = "none";
|
||||
defparam out5 .multabsaturate_pipeline_clear = "none";
|
||||
defparam out5 .multcdsaturate_pipeline_clear = "none";
|
||||
defparam out5 .mode0_clock = "none";
|
||||
defparam out5 .mode1_clock = "none";
|
||||
defparam out5 .zeroacc1_clock = "none";
|
||||
defparam out5 .saturate1_clock = "none";
|
||||
defparam out5 .mode0_pipeline_clock = "none";
|
||||
defparam out5 .mode1_pipeline_clock = "none";
|
||||
defparam out5 .zeroacc1_pipeline_clock = "none";
|
||||
defparam out5 .saturate1_pipeline_clock = "none";
|
||||
defparam out5 .mode0_clear = "none";
|
||||
defparam out5 .mode1_clear = "none";
|
||||
defparam out5 .zeroacc1_clear = "none";
|
||||
defparam out5 .saturate1_clear = "none";
|
||||
defparam out5 .mode0_pipeline_clear = "none";
|
||||
defparam out5 .mode1_pipeline_clear = "none";
|
||||
defparam out5 .zeroacc1_pipeline_clear = "none";
|
||||
defparam out5 .saturate1_pipeline_clear = "none";
|
||||
defparam out5 .output1_clock = "none";
|
||||
defparam out5 .output2_clock = "none";
|
||||
defparam out5 .output3_clock = "none";
|
||||
defparam out5 .output4_clock = "none";
|
||||
defparam out5 .output5_clock = "none";
|
||||
defparam out5 .output6_clock = "none";
|
||||
defparam out5 .output7_clock = "none";
|
||||
defparam out5 .output1_clear = "none";
|
||||
defparam out5 .output2_clear = "none";
|
||||
defparam out5 .output3_clear = "none";
|
||||
defparam out5 .output4_clear = "none";
|
||||
defparam out5 .output5_clear = "none";
|
||||
defparam out5 .output6_clear = "none";
|
||||
defparam out5 .output7_clear = "none";
|
||||
defparam out5 .dataa_forced_to_zero = "no";
|
||||
defparam out5 .datac_forced_to_zero = "no";
|
||||
defparam out5 .output_clock = "0";
|
||||
defparam out5 .zeroacc_clock = "none";
|
||||
defparam out5 .signa_clock = "none";
|
||||
defparam out5 .signb_clock = "none";
|
||||
defparam out5 .zeroacc_pipeline_clock = "none";
|
||||
defparam out5 .signa_pipeline_clock = "none";
|
||||
defparam out5 .signb_pipeline_clock = "none";
|
||||
defparam out5 .zeroacc_clear = "none";
|
||||
defparam out5 .signa_clear = "none";
|
||||
defparam out5 .signb_clear = "none";
|
||||
defparam out5 .output_clear = "0";
|
||||
defparam out5 .zeroacc_pipeline_clear = "none";
|
||||
defparam out5 .signa_pipeline_clear = "none";
|
||||
defparam out5 .signb_pipeline_clear = "none";
|
||||
|
||||
endmodule
|
391
Advanced Synthesis Cookbook/arithmetic/mult_shift.v
Normal file
391
Advanced Synthesis Cookbook/arithmetic/mult_shift.v
Normal file
@ -0,0 +1,391 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 03-31-2006
|
||||
//
|
||||
// mult_32_32 : 32 x 32 pipelined multiply with sign control
|
||||
//
|
||||
// mult_shift_32_32 : 32 x 32 pipelined multiply with sign control
|
||||
// and shift-rot mode. Derived from NIOS ALU design.
|
||||
//
|
||||
|
||||
///////////////////////////////////////////
|
||||
// 18 x 18 mult native building block
|
||||
///////////////////////////////////////////
|
||||
|
||||
module mac_mult_18_18 (clk,ena,rst,sign_a,sign_b,data_a,data_b,data_o);
|
||||
input clk,ena,rst;
|
||||
input sign_a,sign_b;
|
||||
input [17:0] data_a;
|
||||
input [17:0] data_b;
|
||||
output [35:0] data_o;
|
||||
|
||||
parameter GND_SIGNA = "false";
|
||||
parameter GND_SIGNB = "false";
|
||||
|
||||
stratixii_mac_mult mult_a (
|
||||
.signa(sign_a),
|
||||
.signb(sign_b),
|
||||
.sourcea(1'b0),
|
||||
.sourceb(1'b0),
|
||||
.round(1'b0),
|
||||
.saturate(1'b0),
|
||||
.clk({1'b0,1'b0,1'b0,clk}),
|
||||
.aclr({1'b0,1'b0,1'b0,rst}),
|
||||
.ena({1'b1,1'b1,1'b1,ena}),
|
||||
.dataa(data_a),
|
||||
.datab(data_b),
|
||||
.scanina(18'b0),
|
||||
.scaninb(18'b0),
|
||||
.scanouta(),
|
||||
.scanoutb(),
|
||||
|
||||
// synthesis translate off
|
||||
// simulation only ports
|
||||
.devpor(1'b1),
|
||||
.devclrn(1'b1),
|
||||
.zeroacc(1'b0),
|
||||
.mode(1'b0),
|
||||
// synthesis translate on
|
||||
|
||||
.dataout(data_o)
|
||||
);
|
||||
|
||||
defparam mult_a .dataa_width = 18;
|
||||
defparam mult_a .datab_width = 18;
|
||||
defparam mult_a .dataa_clock = "0";
|
||||
defparam mult_a .datab_clock = "0";
|
||||
defparam mult_a .signa_clock = "0";
|
||||
defparam mult_a .signb_clock = "0";
|
||||
defparam mult_a .output_clock = "none";
|
||||
defparam mult_a .dataa_clear = "0";
|
||||
defparam mult_a .datab_clear = "0";
|
||||
defparam mult_a .signa_clear = "0";
|
||||
defparam mult_a .signb_clear = "0";
|
||||
defparam mult_a .output_clear = "none";
|
||||
defparam mult_a .round_clock = "none";
|
||||
defparam mult_a .saturate_clock = "none";
|
||||
defparam mult_a .mode_clock = "none";
|
||||
defparam mult_a .zeroacc_clock = "none";
|
||||
defparam mult_a .round_clear = "none";
|
||||
defparam mult_a .saturate_clear = "none";
|
||||
defparam mult_a .mode_clear = "none";
|
||||
defparam mult_a .zeroacc_clear = "none";
|
||||
defparam mult_a .bypass_multiplier = "no";
|
||||
defparam mult_a .dynamic_mode = "no";
|
||||
defparam mult_a .signa_internally_grounded = GND_SIGNA;
|
||||
defparam mult_a .signb_internally_grounded = GND_SIGNB;
|
||||
endmodule
|
||||
|
||||
///////////////////////////////////////////
|
||||
// 36 x 36 MAC output building block
|
||||
///////////////////////////////////////////
|
||||
|
||||
module mac_out (clk,ena_in,ena_out,rst,sign_a,sign_b,data_a,data_b,data_c,data_d,data_o);
|
||||
input clk,ena_in,ena_out,rst;
|
||||
input sign_a,sign_b;
|
||||
input [35:0] data_a,data_b,data_c,data_d;
|
||||
output [71:0] data_o;
|
||||
|
||||
stratixii_mac_out m_out (
|
||||
.multabsaturate(1'b0),
|
||||
.multcdsaturate(1'b0),
|
||||
.signa(sign_a),
|
||||
.signb(sign_b),
|
||||
.clk({1'b0,1'b0,clk,clk}),
|
||||
.aclr({1'b0,1'b0,rst,1'b0}),
|
||||
.ena({1'b1,1'b1,ena_out,ena_in}),
|
||||
.dataa(data_a),
|
||||
.datab(data_b),
|
||||
.datac(data_c),
|
||||
.datad(data_d),
|
||||
.dataout(data_o),
|
||||
|
||||
// synthesis translate off
|
||||
// simulation only ports
|
||||
.saturate(1'b0),
|
||||
.saturate1(1'b0),
|
||||
.devpor(1'b1),
|
||||
.devclrn(1'b1),
|
||||
.zeroacc(1'b0),
|
||||
.zeroacc1(1'b0),
|
||||
.mode0(1'b0),
|
||||
.mode1(1'b0),
|
||||
.accoverflow(),
|
||||
// synthesis translate on
|
||||
|
||||
.round0(1'b0),
|
||||
.round1(1'b0),
|
||||
.addnsub0(1'b0),
|
||||
.addnsub1(1'b0)
|
||||
);
|
||||
defparam m_out .operation_mode = "36_bit_multiply";
|
||||
defparam m_out .dataa_width = 36;
|
||||
defparam m_out .datab_width = 36;
|
||||
defparam m_out .datac_width = 36;
|
||||
defparam m_out .datad_width = 36;
|
||||
defparam m_out .dataout_width = 72;
|
||||
defparam m_out .addnsub0_clock = "none";
|
||||
defparam m_out .addnsub1_clock = "none";
|
||||
defparam m_out .zeroacc_clock = "none";
|
||||
defparam m_out .signa_clock = "0";
|
||||
defparam m_out .signb_clock = "0";
|
||||
defparam m_out .round0_clock = "none";
|
||||
defparam m_out .round1_clock = "none";
|
||||
defparam m_out .saturate_clock = "none";
|
||||
defparam m_out .multabsaturate_clock = "none";
|
||||
defparam m_out .multcdsaturate_clock = "none";
|
||||
defparam m_out .mode0_clock = "none";
|
||||
defparam m_out .mode1_clock = "none";
|
||||
defparam m_out .zeroacc1_clock = "none";
|
||||
defparam m_out .saturate1_clock = "none";
|
||||
defparam m_out .output_clock = "1";
|
||||
defparam m_out .addnsub0_pipeline_clock = "none";
|
||||
defparam m_out .addnsub1_pipeline_clock = "none";
|
||||
defparam m_out .zeroacc_pipeline_clock = "none";
|
||||
defparam m_out .signa_pipeline_clock = "none";
|
||||
defparam m_out .signb_pipeline_clock = "none";
|
||||
defparam m_out .round0_pipeline_clock = "none";
|
||||
defparam m_out .round1_pipeline_clock = "none";
|
||||
defparam m_out .saturate_pipeline_clock = "none";
|
||||
defparam m_out .multabsaturate_pipeline_clock = "none";
|
||||
defparam m_out .multcdsaturate_pipeline_clock = "none";
|
||||
defparam m_out .mode0_pipeline_clock = "none";
|
||||
defparam m_out .mode1_pipeline_clock = "none";
|
||||
defparam m_out .zeroacc1_pipeline_clock = "none";
|
||||
defparam m_out .saturate1_pipeline_clock = "none";
|
||||
defparam m_out .addnsub0_clear = "none";
|
||||
defparam m_out .addnsub1_clear = "none";
|
||||
defparam m_out .zeroacc_clear = "none";
|
||||
defparam m_out .signa_clear = "1";
|
||||
defparam m_out .signb_clear = "1";
|
||||
defparam m_out .round0_clear = "none";
|
||||
defparam m_out .round1_clear = "none";
|
||||
defparam m_out .saturate_clear = "none";
|
||||
defparam m_out .multabsaturate_clear = "none";
|
||||
defparam m_out .multcdsaturate_clear = "none";
|
||||
defparam m_out .mode0_clear = "none";
|
||||
defparam m_out .mode1_clear = "none";
|
||||
defparam m_out .zeroacc1_clear = "none";
|
||||
defparam m_out .saturate1_clear = "none";
|
||||
defparam m_out .output_clear = "1";
|
||||
defparam m_out .addnsub0_pipeline_clear = "none";
|
||||
defparam m_out .addnsub1_pipeline_clear = "none";
|
||||
defparam m_out .zeroacc_pipeline_clear = "none";
|
||||
defparam m_out .signa_pipeline_clear = "none";
|
||||
defparam m_out .signb_pipeline_clear = "none";
|
||||
defparam m_out .round0_pipeline_clear = "none";
|
||||
defparam m_out .round1_pipeline_clear = "none";
|
||||
defparam m_out .saturate_pipeline_clear = "none";
|
||||
defparam m_out .multabsaturate_pipeline_clear = "none";
|
||||
defparam m_out .multcdsaturate_pipeline_clear = "none";
|
||||
defparam m_out .mode0_pipeline_clear = "none";
|
||||
defparam m_out .mode1_pipeline_clear = "none";
|
||||
defparam m_out .zeroacc1_pipeline_clear = "none";
|
||||
defparam m_out .saturate1_pipeline_clear = "none";
|
||||
defparam m_out .output1_clock = "none";
|
||||
defparam m_out .output2_clock = "none";
|
||||
defparam m_out .output3_clock = "none";
|
||||
defparam m_out .output4_clock = "none";
|
||||
defparam m_out .output5_clock = "none";
|
||||
defparam m_out .output6_clock = "none";
|
||||
defparam m_out .output7_clock = "none";
|
||||
defparam m_out .output1_clear = "none";
|
||||
defparam m_out .output2_clear = "none";
|
||||
defparam m_out .output3_clear = "none";
|
||||
defparam m_out .output4_clear = "none";
|
||||
defparam m_out .output5_clear = "none";
|
||||
defparam m_out .output6_clear = "none";
|
||||
defparam m_out .output7_clear = "none";
|
||||
defparam m_out .dataa_forced_to_zero = "no";
|
||||
defparam m_out .datac_forced_to_zero = "no";
|
||||
endmodule
|
||||
|
||||
///////////////////////////////////////////
|
||||
// 32x32 mult with sign control
|
||||
///////////////////////////////////////////
|
||||
|
||||
module mult_32_32 (clk,ena_in,ena_out,rst,a_signed,b_signed,data_a,data_b,data_o);
|
||||
input clk,ena_in,ena_out,rst;
|
||||
input a_signed,b_signed;
|
||||
input [31:0] data_a,data_b;
|
||||
output [63:0] data_o;
|
||||
|
||||
wire [35:0] m0_out,m1_out,m2_out,m3_out;
|
||||
wire [71:0] m_out;
|
||||
|
||||
mac_mult_18_18 m0 (.clk(clk),.ena(ena_in),.rst(rst),
|
||||
.sign_a(a_signed), .sign_b(b_signed),
|
||||
.data_a({data_a[13:0],4'b0}),
|
||||
.data_b({data_b[13:0],4'b0}),
|
||||
.data_o(m0_out));
|
||||
defparam m0 .GND_SIGNA = "true";
|
||||
defparam m0 .GND_SIGNB = "true";
|
||||
|
||||
mac_mult_18_18 m1 (.clk(clk),.ena(ena_in),.rst(rst),
|
||||
.sign_a(a_signed), .sign_b(b_signed),
|
||||
.data_a(data_a[31:14]),
|
||||
.data_b(data_b[31:14]),
|
||||
.data_o(m1_out));
|
||||
defparam m1 .GND_SIGNA = "false";
|
||||
defparam m1 .GND_SIGNB = "false";
|
||||
|
||||
mac_mult_18_18 m2 (.clk(clk),.ena(ena_in),.rst(rst),
|
||||
.sign_a(a_signed), .sign_b(b_signed),
|
||||
.data_a(data_a[31:14]),
|
||||
.data_b({data_b[13:0],4'b0}),
|
||||
.data_o(m2_out));
|
||||
defparam m2 .GND_SIGNA = "false";
|
||||
defparam m2 .GND_SIGNB = "true";
|
||||
|
||||
mac_mult_18_18 m3 (.clk(clk),.ena(ena_in),.rst(rst),
|
||||
.sign_a(a_signed), .sign_b(b_signed),
|
||||
.data_a({data_a[13:0],4'b0}),
|
||||
.data_b(data_b[31:14]),
|
||||
.data_o(m3_out));
|
||||
defparam m3 .GND_SIGNA = "true";
|
||||
defparam m3 .GND_SIGNB = "false";
|
||||
|
||||
mac_out mo (.clk(clk),.ena_in(ena_in),.ena_out(ena_out),.rst(rst),
|
||||
.sign_a(a_signed), .sign_b(b_signed),
|
||||
.data_a(m0_out),.data_b(m1_out),.data_c(m2_out),.data_d(m3_out),
|
||||
.data_o(m_out));
|
||||
|
||||
assign data_o = m_out[71:8];
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// 32x32 mult with sign control / shift / rotate
|
||||
///////////////////////////////////////////////////
|
||||
|
||||
module mult_shift_32_32 (clk,ena_in,ena_out,rst,
|
||||
shift_not_mult,direction_right,shift_not_rot,
|
||||
a_signed,b_signed,
|
||||
data_a,data_b,data_o
|
||||
);
|
||||
input clk,ena_in,ena_out,rst;
|
||||
input a_signed,b_signed;
|
||||
input shift_not_mult,direction_right,shift_not_rot;
|
||||
input [31:0] data_a,data_b;
|
||||
output [63:0] data_o;
|
||||
|
||||
wire [35:0] m0_out,m1_out,m2_out,m3_out;
|
||||
wire [71:0] m_out;
|
||||
|
||||
wire [31:0] data_b_adj;
|
||||
|
||||
// ignore sign A when rotating
|
||||
wire a_sign_int = a_signed & (!shift_not_mult | shift_not_rot);
|
||||
|
||||
// ignore sign B when rotating or shifting
|
||||
wire b_sign_int = b_signed & !shift_not_mult;
|
||||
|
||||
// compute 2^n using 5 bits of input B for shift and rotate modes
|
||||
// before the 1st clock edge.
|
||||
wire [31:0] data_b_twon /* synthesis keep */;
|
||||
genvar i;
|
||||
generate
|
||||
for (i=0; i<32; i=i+1)
|
||||
begin : twon
|
||||
assign data_b_twon[i] = (!direction_right && (data_b[4:0] == i)) ||
|
||||
(direction_right && (data_b[4:0] == (32-i))) ||
|
||||
(direction_right && (data_b[4:0] == 0) && (i == 0));
|
||||
end
|
||||
endgenerate
|
||||
assign data_b_adj = shift_not_mult ? data_b_twon : data_b;
|
||||
|
||||
// create delayed shift controls.
|
||||
reg shift_not_mult_r,direction_right_r,shift_not_rot_r;
|
||||
reg shift_not_mult_rr,direction_right_rr,shift_not_rot_rr;
|
||||
always @(posedge clk or posedge rst) begin
|
||||
if (rst) begin
|
||||
shift_not_mult_r <= 1'b0;
|
||||
direction_right_r <= 1'b0;
|
||||
shift_not_rot_r <= 1'b0;
|
||||
shift_not_mult_rr <= 1'b0;
|
||||
direction_right_rr <= 1'b0;
|
||||
shift_not_rot_rr <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
if (ena_in) begin
|
||||
shift_not_mult_r <= shift_not_mult;
|
||||
shift_not_rot_r <= shift_not_rot;
|
||||
|
||||
// if some joker asks for right 0 change it to
|
||||
// left 0.
|
||||
direction_right_r <= (|data_b[4:0]) && direction_right;
|
||||
end
|
||||
|
||||
if (ena_out) begin
|
||||
shift_not_mult_rr <= shift_not_mult_r;
|
||||
direction_right_rr <= direction_right_r;
|
||||
shift_not_rot_rr <= shift_not_rot_r;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// 32 x 32 MAC multiplier
|
||||
mac_mult_18_18 m0 (.clk(clk),.ena(ena_in),.rst(rst),
|
||||
.sign_a(a_sign_int), .sign_b(b_sign_int),
|
||||
.data_a({data_a[13:0],4'b0}),
|
||||
.data_b({data_b_adj[13:0],4'b0}),
|
||||
.data_o(m0_out));
|
||||
defparam m0 .GND_SIGNA = "true";
|
||||
defparam m0 .GND_SIGNB = "true";
|
||||
|
||||
mac_mult_18_18 m1 (.clk(clk),.ena(ena_in),.rst(rst),
|
||||
.sign_a(a_sign_int), .sign_b(b_sign_int),
|
||||
.data_a(data_a[31:14]),
|
||||
.data_b(data_b_adj[31:14]),
|
||||
.data_o(m1_out));
|
||||
defparam m1 .GND_SIGNA = "false";
|
||||
defparam m1 .GND_SIGNB = "false";
|
||||
|
||||
mac_mult_18_18 m2 (.clk(clk),.ena(ena_in),.rst(rst),
|
||||
.sign_a(a_sign_int), .sign_b(b_sign_int),
|
||||
.data_a(data_a[31:14]),
|
||||
.data_b({data_b_adj[13:0],4'b0}),
|
||||
.data_o(m2_out));
|
||||
defparam m2 .GND_SIGNA = "false";
|
||||
defparam m2 .GND_SIGNB = "true";
|
||||
|
||||
mac_mult_18_18 m3 (.clk(clk),.ena(ena_in),.rst(rst),
|
||||
.sign_a(a_sign_int), .sign_b(b_sign_int),
|
||||
.data_a({data_a[13:0],4'b0}),
|
||||
.data_b(data_b_adj[31:14]),
|
||||
.data_o(m3_out));
|
||||
defparam m3 .GND_SIGNA = "true";
|
||||
defparam m3 .GND_SIGNB = "false";
|
||||
|
||||
mac_out mo (.clk(clk),.ena_in(ena_in),.ena_out(ena_out),.rst(rst),
|
||||
.sign_a(a_sign_int), .sign_b(b_sign_int),
|
||||
.data_a(m0_out),.data_b(m1_out),.data_c(m2_out),.data_d(m3_out),
|
||||
.data_o(m_out));
|
||||
|
||||
// output side shifter logic
|
||||
assign data_o = !shift_not_mult_rr ? m_out[71:8] :
|
||||
(shift_not_rot_rr ? (direction_right_rr ? m_out[71:40] : m_out[39:8])
|
||||
: (m_out[71:40] | m_out[39:8]));
|
||||
|
||||
endmodule
|
254
Advanced Synthesis Cookbook/arithmetic/mult_shift_tb.v
Normal file
254
Advanced Synthesis Cookbook/arithmetic/mult_shift_tb.v
Normal file
@ -0,0 +1,254 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Testbench
|
||||
///////////////////////////////////////////
|
||||
// Needs the altmult_add model in quartus/eda/sim_lib/altera_mf.v
|
||||
// as well as the stratix II atom models.
|
||||
|
||||
module mult_shift_tb ();
|
||||
|
||||
reg fail;
|
||||
reg clk,ena_in,ena_out,rst,a_signed,b_signed;
|
||||
reg shift_not_mult,direction_right,shift_not_rot;
|
||||
reg [31:0] data_a,data_b;
|
||||
wire [63:0] data_o_w, data_o_x, data_o_y, data_o_z;
|
||||
|
||||
mult_shift_32_32 w (
|
||||
.clk(clk),.ena_in(ena_in),.ena_out(ena_out),.rst(rst),
|
||||
.a_signed(a_signed),.b_signed(b_signed),
|
||||
.data_a(data_a),.data_b(data_b),
|
||||
.data_o(data_o_w),
|
||||
.shift_not_mult(shift_not_mult),
|
||||
.direction_right(direction_right),
|
||||
.shift_not_rot(shift_not_rot)
|
||||
);
|
||||
|
||||
mult_32_32 x (.clk(clk),.ena_in(ena_in),.ena_out(ena_out),.rst(rst),
|
||||
.a_signed(a_signed),.b_signed(b_signed),
|
||||
.data_a(data_a),.data_b(data_b),
|
||||
.data_o(data_o_x));
|
||||
|
||||
cpu_mult_cell y (.A_en(ena_out),
|
||||
.E_ctrl_mul_cell_src1_signed(a_signed),
|
||||
.E_ctrl_mul_cell_src2_signed(b_signed),
|
||||
.E_src1_mul_cell(data_a),
|
||||
.E_src2_mul_cell(data_b),
|
||||
.M_en(ena_in),
|
||||
.clk(clk),
|
||||
.reset_n(!rst),
|
||||
.A_mul_cell_result(data_o_y)
|
||||
);
|
||||
|
||||
|
||||
///////////////////////////////////////////
|
||||
// functional model
|
||||
///////////////////////////////////////////
|
||||
reg mult_showing_r, mult_showing_rr;
|
||||
wire signed [32:0] tmp_a;
|
||||
wire signed [32:0] tmp_b;
|
||||
wire signed [71:0] tmp_mult;
|
||||
assign tmp_a = {a_signed & data_a[31],data_a};
|
||||
assign tmp_b = {b_signed & data_b[31],data_b};
|
||||
assign tmp_mult = tmp_a * tmp_b;
|
||||
|
||||
wire [31:0] tmp_shr = data_a >> data_b[4:0];
|
||||
wire [31:0] tmp_shl = data_a << data_b[4:0];
|
||||
wire [63:0] double_a = {data_a,data_a};
|
||||
wire [63:0] signext_a = {{32{a_signed & data_a[31]}} ,data_a};
|
||||
wire [31:0] tmp_ror = (double_a >> data_b[4:0]);
|
||||
wire [31:0] tmp_rol = (double_a << data_b[4:0]) >> 32;
|
||||
wire [31:0] tmp_asr = (signext_a >> data_b[4:0]);
|
||||
|
||||
wire [63:0] tmp_result = !shift_not_mult ? tmp_mult[63:0] :
|
||||
{32'b0,
|
||||
(shift_not_rot ? (direction_right ?
|
||||
(a_signed ? tmp_asr : tmp_shr) : tmp_shl) :
|
||||
(direction_right ? tmp_ror : tmp_rol)
|
||||
)};
|
||||
|
||||
reg [63:0] wait_x,wait_y;
|
||||
|
||||
always @(posedge clk or posedge rst) begin
|
||||
if (rst) begin
|
||||
wait_x <= 0;
|
||||
wait_y <= 0;
|
||||
mult_showing_r <= 1'b0;
|
||||
mult_showing_rr <= 1'b0;
|
||||
|
||||
end
|
||||
else begin
|
||||
if (ena_in) begin
|
||||
wait_x <= tmp_result[63:0];
|
||||
mult_showing_r <= !shift_not_mult;
|
||||
end
|
||||
if (ena_out) begin
|
||||
wait_y <= wait_x;
|
||||
mult_showing_rr <= mult_showing_r;
|
||||
end
|
||||
end
|
||||
end
|
||||
assign data_o_z = wait_y;
|
||||
|
||||
|
||||
///////////////////////////////////////////
|
||||
// test stim and verify
|
||||
///////////////////////////////////////////
|
||||
|
||||
initial begin
|
||||
clk = 1;
|
||||
rst = 0;
|
||||
ena_in = 1;
|
||||
ena_out = 1;
|
||||
fail = 0;
|
||||
a_signed = 0;
|
||||
b_signed = 0;
|
||||
#10 rst = 1;
|
||||
#10 rst = 0;
|
||||
#5000000 if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
always @(negedge clk) begin
|
||||
ena_in = $random;
|
||||
ena_out = $random;
|
||||
shift_not_mult = $random;
|
||||
direction_right = $random;
|
||||
shift_not_rot = $random;
|
||||
a_signed = $random;
|
||||
b_signed = $random;
|
||||
data_a = $random;
|
||||
data_b = $random;
|
||||
end
|
||||
|
||||
always begin
|
||||
#500 clk = ~clk;
|
||||
end
|
||||
|
||||
always @(negedge clk) begin
|
||||
|
||||
// compare pure multiplier against altmult version
|
||||
#10 if (data_o_x !== data_o_y) begin
|
||||
$display ("Simple MULT Mismatch at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
|
||||
// compare multshift unit against functional model
|
||||
if (data_o_w !== data_o_z) begin
|
||||
$display ("Shift MULT unit Mismatch at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
|
||||
// when in multiply mode compare between mult and multshift
|
||||
// units
|
||||
if (mult_showing_rr) begin
|
||||
if (data_o_x !== data_o_z) begin
|
||||
$display ("Mult showing - cross unit mismatch at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// altmult based multiplier used by NIOS, for
|
||||
// testing purposes.
|
||||
//
|
||||
// The altmult_add model is in the quartus/eda/sim_lib/altera_mf.v
|
||||
// library.
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
module cpu_mult_cell (
|
||||
// inputs:
|
||||
A_en,
|
||||
E_ctrl_mul_cell_src1_signed,
|
||||
E_ctrl_mul_cell_src2_signed,
|
||||
E_src1_mul_cell,
|
||||
E_src2_mul_cell,
|
||||
M_en,
|
||||
clk,
|
||||
reset_n,
|
||||
|
||||
// outputs:
|
||||
A_mul_cell_result
|
||||
)
|
||||
;
|
||||
|
||||
output [ 63: 0] A_mul_cell_result;
|
||||
input A_en;
|
||||
input E_ctrl_mul_cell_src1_signed;
|
||||
input E_ctrl_mul_cell_src2_signed;
|
||||
input [ 31: 0] E_src1_mul_cell;
|
||||
input [ 31: 0] E_src2_mul_cell;
|
||||
input M_en;
|
||||
input clk;
|
||||
input reset_n;
|
||||
|
||||
wire [ 63: 0] A_mul_cell_result;
|
||||
wire mul_clr;
|
||||
assign mul_clr = ~reset_n;
|
||||
altmult_add the_altmult_add
|
||||
(
|
||||
.aclr0 (mul_clr),
|
||||
.aclr1 (mul_clr),
|
||||
.clock0 (clk),
|
||||
.clock1 (clk),
|
||||
.dataa (E_src1_mul_cell),
|
||||
.datab (E_src2_mul_cell),
|
||||
.ena0 (M_en),
|
||||
.ena1 (A_en),
|
||||
.result (A_mul_cell_result),
|
||||
.signa (E_ctrl_mul_cell_src1_signed),
|
||||
.signb (E_ctrl_mul_cell_src2_signed)
|
||||
);
|
||||
|
||||
defparam the_altmult_add.addnsub_multiplier_aclr1 = "UNUSED",
|
||||
the_altmult_add.addnsub_multiplier_pipeline_aclr1 = "UNUSED",
|
||||
the_altmult_add.addnsub_multiplier_register1 = "CLOCK0",
|
||||
the_altmult_add.dedicated_multiplier_circuitry = "YES",
|
||||
the_altmult_add.input_aclr_a0 = "ACLR0",
|
||||
the_altmult_add.input_aclr_b0 = "ACLR0",
|
||||
the_altmult_add.input_register_a0 = "CLOCK0",
|
||||
the_altmult_add.input_register_b0 = "CLOCK0",
|
||||
the_altmult_add.input_source_a0 = "DATAA",
|
||||
the_altmult_add.input_source_b0 = "DATAB",
|
||||
the_altmult_add.lpm_type = "altmult_add",
|
||||
the_altmult_add.multiplier1_direction = "ADD",
|
||||
the_altmult_add.multiplier_register0 = "UNREGISTERED",
|
||||
the_altmult_add.number_of_multipliers = 1,
|
||||
the_altmult_add.output_aclr = "ACLR1",
|
||||
the_altmult_add.output_register = "CLOCK1",
|
||||
the_altmult_add.signed_aclr_a = "ACLR0",
|
||||
the_altmult_add.signed_aclr_b = "ACLR0",
|
||||
the_altmult_add.signed_pipeline_register_a = "UNREGISTERED",
|
||||
the_altmult_add.signed_pipeline_register_b = "UNREGISTERED",
|
||||
the_altmult_add.signed_register_a = "CLOCK0",
|
||||
the_altmult_add.signed_register_b = "CLOCK0",
|
||||
the_altmult_add.width_a = 32,
|
||||
the_altmult_add.width_b = 32,
|
||||
the_altmult_add.width_result = 64;
|
||||
|
||||
|
||||
endmodule
|
||||
|
81
Advanced Synthesis Cookbook/arithmetic/pipeline_add.v
Normal file
81
Advanced Synthesis Cookbook/arithmetic/pipeline_add.v
Normal file
@ -0,0 +1,81 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 09-01-2006
|
||||
//
|
||||
// Adder with one level of pipeline (embedded in the carry chain).
|
||||
// This is the most efficient way to speed up arithmetic when
|
||||
// latency is available.
|
||||
//
|
||||
// For some additional speed in return for more area you can duplicate
|
||||
// the more significant chain and do carry-select. Shorten the less
|
||||
// significant half to balance the delay.
|
||||
//
|
||||
|
||||
module pipeline_add (clk,rst,a,b,o);
|
||||
|
||||
parameter LS_WIDTH = 10;
|
||||
parameter MS_WIDTH = 10;
|
||||
parameter WIDTH = LS_WIDTH + MS_WIDTH;
|
||||
|
||||
input [WIDTH-1:0] a,b;
|
||||
input clk,rst;
|
||||
output [WIDTH-1:0] o;
|
||||
reg [WIDTH-1:0] o;
|
||||
|
||||
// Build the less significant adder with an extra bit on the top to get
|
||||
// the carry chain onto the normal routing.
|
||||
reg [LS_WIDTH-1+1:0] ls_adder;
|
||||
wire cross_carry = ls_adder[LS_WIDTH];
|
||||
always @(posedge clk or posedge rst) begin
|
||||
if (rst) ls_adder <= 1'b0;
|
||||
else ls_adder <= {1'b0,a[LS_WIDTH-1:0]} + {1'b0,b[LS_WIDTH-1:0]};
|
||||
end
|
||||
|
||||
// the more significant data needs to wait a tick for the carry
|
||||
// signal to be ready
|
||||
reg [MS_WIDTH-1:0] ms_data_a,ms_data_b;
|
||||
always @(posedge clk or posedge rst) begin
|
||||
if (rst) begin
|
||||
ms_data_a <= 0;
|
||||
ms_data_b <= 0;
|
||||
end
|
||||
else begin
|
||||
ms_data_a <= a[WIDTH-1:WIDTH-MS_WIDTH];
|
||||
ms_data_b <= b[WIDTH-1:WIDTH-MS_WIDTH];
|
||||
end
|
||||
end
|
||||
|
||||
// Build the more significant adder with an extra low bit to incorporate
|
||||
// the carry from the split lower chain.
|
||||
wire [MS_WIDTH-1+1:0] ms_adder;
|
||||
assign ms_adder = {ms_data_a,cross_carry} +
|
||||
{ms_data_b,cross_carry};
|
||||
|
||||
// collect the sum back together and register, drop the two internal bits
|
||||
always @(posedge clk or posedge rst) begin
|
||||
if (rst) o <= 0;
|
||||
else o <= {ms_adder[MS_WIDTH:1],ls_adder[LS_WIDTH-1:0]};
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
83
Advanced Synthesis Cookbook/arithmetic/pipeline_add_msb.v
Normal file
83
Advanced Synthesis Cookbook/arithmetic/pipeline_add_msb.v
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// liu - 06-11-2006
|
||||
//
|
||||
// Adder with one level of pipeline (embedded in the carry chain).
|
||||
// This is the most efficient way to speed up arithmetic when
|
||||
// latency is available.
|
||||
//
|
||||
// Modification to expose the unregistered most significant bit
|
||||
// for use in carry select
|
||||
//
|
||||
|
||||
module pipeline_add_msb (clk,rst,a,b,o,msb);
|
||||
|
||||
parameter LS_WIDTH = 10;
|
||||
parameter MS_WIDTH = 10;
|
||||
parameter WIDTH = LS_WIDTH + MS_WIDTH;
|
||||
|
||||
input [WIDTH-1:0] a,b;
|
||||
input clk,rst;
|
||||
output [WIDTH-1:0] o;
|
||||
output msb;
|
||||
reg [WIDTH-1:0] o;
|
||||
|
||||
// Build the less significant adder with an extra bit on the top to get
|
||||
// the carry chain onto the normal routing.
|
||||
reg [LS_WIDTH-1+1:0] ls_adder;
|
||||
wire cross_carry = ls_adder[LS_WIDTH];
|
||||
always @(posedge clk or posedge rst) begin
|
||||
if (rst) ls_adder <= 1'b0;
|
||||
else ls_adder <= {1'b0,a[LS_WIDTH-1:0]} + {1'b0,b[LS_WIDTH-1:0]};
|
||||
end
|
||||
|
||||
// the more significant data needs to wait a tick for the carry
|
||||
// signal to be ready
|
||||
reg [MS_WIDTH-1:0] ms_data_a,ms_data_b;
|
||||
always @(posedge clk or posedge rst) begin
|
||||
if (rst) begin
|
||||
ms_data_a <= 0;
|
||||
ms_data_b <= 0;
|
||||
end
|
||||
else begin
|
||||
ms_data_a <= a[WIDTH-1:WIDTH-MS_WIDTH];
|
||||
ms_data_b <= b[WIDTH-1:WIDTH-MS_WIDTH];
|
||||
end
|
||||
end
|
||||
|
||||
// Build the more significant adder with an extra low bit to incorporate
|
||||
// the carry from the split lower chain.
|
||||
wire [MS_WIDTH-1+1:0] ms_adder;
|
||||
assign ms_adder = {ms_data_a,cross_carry} +
|
||||
{ms_data_b,cross_carry};
|
||||
|
||||
assign msb = ms_adder[MS_WIDTH];
|
||||
|
||||
// collect the sum back together and register, drop the two internal bits
|
||||
always @(posedge clk or posedge rst) begin
|
||||
if (rst) o <= 0;
|
||||
else o <= {ms_adder[MS_WIDTH:1],ls_adder[LS_WIDTH-1:0]};
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
82
Advanced Synthesis Cookbook/arithmetic/pipeline_add_tb.v
Normal file
82
Advanced Synthesis Cookbook/arithmetic/pipeline_add_tb.v
Normal file
@ -0,0 +1,82 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 01-04-2007
|
||||
|
||||
module pipeline_add_tb ();
|
||||
parameter LS_WIDTH = 15;
|
||||
parameter MS_WIDTH = 20;
|
||||
parameter WIDTH = LS_WIDTH + MS_WIDTH;
|
||||
|
||||
reg [WIDTH-1:0] a,b;
|
||||
reg rst,clk;
|
||||
wire [WIDTH-1:0] oa;
|
||||
reg first = 1'b1;
|
||||
|
||||
// functional model
|
||||
reg [WIDTH-1:0] ob,ob_delay;
|
||||
always @(posedge clk or posedge rst) begin
|
||||
if (rst) begin
|
||||
ob_delay <= 0;
|
||||
ob <= 0;
|
||||
end
|
||||
else begin
|
||||
ob_delay <= ob;
|
||||
ob <= a + b;
|
||||
end
|
||||
end
|
||||
|
||||
// DUT
|
||||
pipeline_add s (.clk(clk),.rst(rst),.a(a),.b(b),.o(oa));
|
||||
defparam s .LS_WIDTH = LS_WIDTH;
|
||||
defparam s .MS_WIDTH = MS_WIDTH;
|
||||
|
||||
// run the clock and spin A and B data
|
||||
always begin
|
||||
#100 clk = ~clk;
|
||||
end
|
||||
always @(negedge clk) begin
|
||||
a = {$random,$random};
|
||||
b = {$random,$random};
|
||||
end
|
||||
|
||||
// verify - ignore the very first tick while the
|
||||
// pipe clears.
|
||||
always @(posedge clk) begin
|
||||
#10 if (!first && oa !== ob_delay) begin
|
||||
$display ("Mismatch at time %d",$time);
|
||||
$stop();
|
||||
end
|
||||
end
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
rst = 0;
|
||||
#10 rst = 1;
|
||||
#10 rst = 0;
|
||||
@(posedge clk)
|
||||
@(negedge clk) first = 0;
|
||||
|
||||
#1000000 $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
endmodule
|
214
Advanced Synthesis Cookbook/arithmetic/select_add.v
Normal file
214
Advanced Synthesis Cookbook/arithmetic/select_add.v
Normal file
@ -0,0 +1,214 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 03-15-2006
|
||||
|
||||
////////////////////////////////////////////////
|
||||
|
||||
module car_select_add (clk,a,b,o);
|
||||
|
||||
parameter BLOCK_SIZE = 14;
|
||||
parameter NUM_BLOCKS = 4;
|
||||
|
||||
localparam DAT_WIDTH = BLOCK_SIZE * NUM_BLOCKS;
|
||||
|
||||
input clk;
|
||||
input [DAT_WIDTH-1:0] a,b;
|
||||
output [DAT_WIDTH:0] o;
|
||||
|
||||
// take care of the 1st block of adder chain
|
||||
wire [BLOCK_SIZE:0] first_add;
|
||||
reg [BLOCK_SIZE-1:0] first_add_r;
|
||||
assign first_add = a[BLOCK_SIZE-1:0] + b[BLOCK_SIZE-1:0];
|
||||
wire first_co = first_add[BLOCK_SIZE];
|
||||
|
||||
// generate the following select blocks
|
||||
wire [NUM_BLOCKS-1:0] car;
|
||||
assign car[0] = first_co;
|
||||
reg last_c_r;
|
||||
genvar i;
|
||||
generate
|
||||
for (i=1; i<NUM_BLOCKS; i=i+1)
|
||||
begin : blk
|
||||
select_block cb (.clk(clk),.ci(car[i-1]),
|
||||
.a(a[i*BLOCK_SIZE+BLOCK_SIZE-1 : i*BLOCK_SIZE]),
|
||||
.b(b[i*BLOCK_SIZE+BLOCK_SIZE-1 : i*BLOCK_SIZE]),
|
||||
.o(o[i*BLOCK_SIZE+BLOCK_SIZE-1 : i*BLOCK_SIZE]),
|
||||
.co (car[i]));
|
||||
defparam cb .WIDTH = BLOCK_SIZE;
|
||||
defparam cb .USE_SLOAD = 0;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// finish up the sum out signals
|
||||
always @(posedge clk) begin
|
||||
first_add_r <= first_add[BLOCK_SIZE-1:0];
|
||||
last_c_r <= car[NUM_BLOCKS-1];
|
||||
end
|
||||
assign o[BLOCK_SIZE-1:0] = first_add_r;
|
||||
assign o[DAT_WIDTH] = last_c_r;
|
||||
|
||||
endmodule
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Compute SUM for both CIN=0 and 1, MUX the
|
||||
// result. Registered sum out, unregistered
|
||||
// carry out
|
||||
////////////////////////////////////////////////
|
||||
module select_block (clk,ci,a,b,o,co);
|
||||
|
||||
parameter WIDTH = 7;
|
||||
parameter USE_SLOAD = 0;
|
||||
|
||||
input clk;
|
||||
input [WIDTH-1:0] a,b;
|
||||
input ci;
|
||||
|
||||
output [WIDTH-1:0] o;
|
||||
reg [WIDTH-1:0] o;
|
||||
output co;
|
||||
|
||||
wire [WIDTH:0] chain_o,chain_z;
|
||||
wire [WIDTH:0] data_a = {1'b0,a};
|
||||
wire [WIDTH:0] data_b = {1'b0,b};
|
||||
wire [WIDTH+1:0] car_o,car_z;
|
||||
assign car_z[0] = 1'b0;
|
||||
assign car_o[0] = 1'b1;
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for (i=0; i<=WIDTH; i=i+1)
|
||||
begin : chn
|
||||
stratixii_lcell_comb w (
|
||||
.dataa(1'b1), .datab(1'b1), .datac(1'b1), .datae(1'b1), .datag(1'b1),
|
||||
.datad(data_a[i]),
|
||||
.dataf(data_b[i]),
|
||||
.cin (car_z[i]),
|
||||
.cout (car_z[i+1]),
|
||||
.sharein (1'b0),
|
||||
.shareout (),
|
||||
.combout(),
|
||||
.sumout (chain_z[i])
|
||||
);
|
||||
defparam w .shared_arith = "off";
|
||||
defparam w .extended_lut = "off";
|
||||
defparam w .lut_mask = 64'h000000ff0000ff00; // d plus f
|
||||
|
||||
stratixii_lcell_comb x (
|
||||
.dataa(1'b1), .datab(1'b1), .datac(1'b1), .datae(1'b1), .datag(1'b1),
|
||||
.datad(data_a[i]),
|
||||
.dataf(data_b[i]),
|
||||
.cin (car_o[i]),
|
||||
.cout (car_o[i+1]),
|
||||
.sharein (1'b0),
|
||||
.shareout (),
|
||||
.combout(),
|
||||
.sumout (chain_o[i])
|
||||
);
|
||||
defparam x .shared_arith = "off";
|
||||
defparam x .extended_lut = "off";
|
||||
defparam x .lut_mask = 64'h000000ff0000ff00; // d plus f
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign co = (ci ? chain_o[WIDTH]: chain_z[WIDTH]);
|
||||
|
||||
generate
|
||||
if (USE_SLOAD) begin
|
||||
wire [WIDTH-1:0] ow;
|
||||
for (i=0; i<WIDTH; i=i+1)
|
||||
begin : regs
|
||||
stratixii_lcell_ff r (
|
||||
.clk (clk),
|
||||
.ena (1'b1),
|
||||
.datain(chain_z[i]),
|
||||
.adatasdata(chain_o[i]),
|
||||
.sclr(1'b0),
|
||||
.aload (1'b0),
|
||||
.aclr (1'b0),
|
||||
.sload (ci),
|
||||
|
||||
// synthesis translate off
|
||||
.devpor (1'b1),
|
||||
.devclrn (1'b1),
|
||||
// synthesis translate on
|
||||
|
||||
.regout (ow[i])
|
||||
);
|
||||
end
|
||||
always @(ow) o <= ow;
|
||||
end
|
||||
else begin
|
||||
// don't do SLOAD
|
||||
always @(posedge clk) begin
|
||||
o <= (ci ? chain_o[WIDTH-1:0] : chain_z[WIDTH-1:0]);
|
||||
end
|
||||
end
|
||||
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
////////////////////////////////////////////////
|
||||
|
||||
module test_add ();
|
||||
|
||||
parameter BLOCK_SIZE = 14;
|
||||
parameter NUM_BLOCKS = 4;
|
||||
parameter DAT_WIDTH = BLOCK_SIZE * NUM_BLOCKS;
|
||||
|
||||
reg [DAT_WIDTH-1:0] a,b;
|
||||
wire [DAT_WIDTH:0] ox;
|
||||
reg [DAT_WIDTH:0] oy;
|
||||
reg clk,fail;
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
a = 0;
|
||||
b = 0;
|
||||
fail = 0;
|
||||
#100000 if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
always begin
|
||||
#100 clk = ~clk;
|
||||
end
|
||||
|
||||
car_select_add la (.clk(clk),.a(a),.b(b),.o(ox));
|
||||
|
||||
always @(posedge clk) begin
|
||||
oy <= a+b;
|
||||
end
|
||||
|
||||
always @(negedge clk) begin
|
||||
a = {$random,$random};
|
||||
b = {$random,$random};
|
||||
if (ox !== oy) begin
|
||||
$display ("Mismatch at time %d",$time);
|
||||
$display (" %x",ox);
|
||||
$display (" %x",oy);
|
||||
fail = 1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -0,0 +1,62 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 03-29-2006
|
||||
// speed test bench for carry select adder
|
||||
|
||||
module select_add_speed_test (clk,a,b,o);
|
||||
|
||||
parameter BLOCK_SIZE = 14;
|
||||
parameter NUM_BLOCKS = 4;
|
||||
parameter DAT_WIDTH = BLOCK_SIZE * NUM_BLOCKS;
|
||||
|
||||
parameter METHOD = 0;
|
||||
|
||||
input clk;
|
||||
input [DAT_WIDTH-1:0] a,b;
|
||||
output [DAT_WIDTH:0] o;
|
||||
|
||||
reg [DAT_WIDTH-1:0] ra,rb;
|
||||
reg [DAT_WIDTH:0] ro;
|
||||
|
||||
always @(posedge clk) begin
|
||||
ra <= a;
|
||||
rb <= b;
|
||||
end
|
||||
|
||||
generate
|
||||
|
||||
if (METHOD == 0) begin
|
||||
|
||||
car_select_add la (.clk(clk),.a(ra),.b(rb),.o(o));
|
||||
defparam la .BLOCK_SIZE = BLOCK_SIZE;
|
||||
defparam la .NUM_BLOCKS = NUM_BLOCKS;
|
||||
end
|
||||
else begin
|
||||
always @(posedge clk) begin
|
||||
ro <= ra + rb;
|
||||
end
|
||||
assign o = ro;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
107
Advanced Synthesis Cookbook/arithmetic/six_three_comp.v
Normal file
107
Advanced Synthesis Cookbook/arithmetic/six_three_comp.v
Normal file
@ -0,0 +1,107 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 05-13-2005
|
||||
//
|
||||
// Six input three output compressor (non-carry adder)
|
||||
//
|
||||
// Maps to 3 Stratix II six luts. Use optimize = speed
|
||||
//
|
||||
|
||||
module six_three_comp (data,sum);
|
||||
|
||||
input [5:0] data;
|
||||
output [2:0] sum;
|
||||
|
||||
reg [2:0] sum /* synthesis keep */;
|
||||
|
||||
always @(data) begin
|
||||
case (data)
|
||||
0: sum=0;
|
||||
1: sum=1;
|
||||
2: sum=1;
|
||||
3: sum=2;
|
||||
4: sum=1;
|
||||
5: sum=2;
|
||||
6: sum=2;
|
||||
7: sum=3;
|
||||
8: sum=1;
|
||||
9: sum=2;
|
||||
10: sum=2;
|
||||
11: sum=3;
|
||||
12: sum=2;
|
||||
13: sum=3;
|
||||
14: sum=3;
|
||||
15: sum=4;
|
||||
16: sum=1;
|
||||
17: sum=2;
|
||||
18: sum=2;
|
||||
19: sum=3;
|
||||
20: sum=2;
|
||||
21: sum=3;
|
||||
22: sum=3;
|
||||
23: sum=4;
|
||||
24: sum=2;
|
||||
25: sum=3;
|
||||
26: sum=3;
|
||||
27: sum=4;
|
||||
28: sum=3;
|
||||
29: sum=4;
|
||||
30: sum=4;
|
||||
31: sum=5;
|
||||
32: sum=1;
|
||||
33: sum=2;
|
||||
34: sum=2;
|
||||
35: sum=3;
|
||||
36: sum=2;
|
||||
37: sum=3;
|
||||
38: sum=3;
|
||||
39: sum=4;
|
||||
40: sum=2;
|
||||
41: sum=3;
|
||||
42: sum=3;
|
||||
43: sum=4;
|
||||
44: sum=3;
|
||||
45: sum=4;
|
||||
46: sum=4;
|
||||
47: sum=5;
|
||||
48: sum=2;
|
||||
49: sum=3;
|
||||
50: sum=3;
|
||||
51: sum=4;
|
||||
52: sum=3;
|
||||
53: sum=4;
|
||||
54: sum=4;
|
||||
55: sum=5;
|
||||
56: sum=3;
|
||||
57: sum=4;
|
||||
58: sum=4;
|
||||
59: sum=5;
|
||||
60: sum=4;
|
||||
61: sum=5;
|
||||
62: sum=5;
|
||||
63: sum=6;
|
||||
default: sum=0;
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
88
Advanced Synthesis Cookbook/arithmetic/split_add.v
Normal file
88
Advanced Synthesis Cookbook/arithmetic/split_add.v
Normal file
@ -0,0 +1,88 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 09-01-2006
|
||||
//
|
||||
// Example of adder using 2 carry chains, with the carry between them on standard
|
||||
// routing. This technique is useful when very long chains are causing placement
|
||||
// difficulty. Should use exactly WIDTH+2 cells.
|
||||
|
||||
module split_add (a,b,o);
|
||||
|
||||
parameter LS_WIDTH = 10;
|
||||
parameter MS_WIDTH = 10;
|
||||
parameter WIDTH = LS_WIDTH + MS_WIDTH;
|
||||
|
||||
input [WIDTH-1:0] a,b;
|
||||
output [WIDTH-1:0] o;
|
||||
wire [WIDTH-1:0] o;
|
||||
|
||||
// Build the less significant adder with an extra bit on the top to get
|
||||
// the carry chain onto the normal routing. The keep pragma prevents
|
||||
// synthesis from undoing the split.
|
||||
|
||||
wire [LS_WIDTH-1+1:0] ls_adder;
|
||||
wire cross_carry = ls_adder[LS_WIDTH] /* synthesis keep */;
|
||||
assign ls_adder = {1'b0,a[LS_WIDTH-1:0]} + {1'b0,b[LS_WIDTH-1:0]};
|
||||
|
||||
// Build the more significant adder with an extra low bit to incorporate
|
||||
// the carry from the split lower chain.
|
||||
|
||||
wire [MS_WIDTH-1+1:0] ms_adder;
|
||||
assign ms_adder = {a[WIDTH-1:WIDTH-MS_WIDTH],cross_carry} +
|
||||
{b[WIDTH-1:WIDTH-MS_WIDTH],cross_carry};
|
||||
|
||||
// collect the sum back together, drop the two internal bits
|
||||
assign o = {ms_adder[MS_WIDTH:1],ls_adder[LS_WIDTH-1:0]};
|
||||
|
||||
endmodule
|
||||
|
||||
/////////////////////////////////
|
||||
|
||||
module split_add_tb ();
|
||||
parameter LS_WIDTH = 15;
|
||||
parameter MS_WIDTH = 20;
|
||||
parameter WIDTH = LS_WIDTH + MS_WIDTH;
|
||||
|
||||
reg [WIDTH-1:0] a,b;
|
||||
wire [WIDTH-1:0] oa,ob;
|
||||
|
||||
assign ob = a + b; // functional model
|
||||
split_add s (.a(a),.b(b),.o(oa));
|
||||
defparam s .LS_WIDTH = LS_WIDTH;
|
||||
defparam s .MS_WIDTH = MS_WIDTH;
|
||||
|
||||
always begin
|
||||
#100
|
||||
a = {$random,$random};
|
||||
b = {$random,$random};
|
||||
#10 if (oa !== ob) begin
|
||||
$display ("Mismatch at time %d",$time);
|
||||
$stop();
|
||||
end
|
||||
end
|
||||
|
||||
initial begin
|
||||
#1000000 $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
endmodule
|
106
Advanced Synthesis Cookbook/arithmetic/sum_of_3bit_pair.v
Normal file
106
Advanced Synthesis Cookbook/arithmetic/sum_of_3bit_pair.v
Normal file
@ -0,0 +1,106 @@
|
||||
// Copyright 2008 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 09-15-2008
|
||||
//
|
||||
// Sum of two 3-bit numbers, targeting exactly four LUTs
|
||||
// {6,6,4,2} inputs
|
||||
//
|
||||
|
||||
module sum_of_3bit_pair
|
||||
(
|
||||
input [2:0] a,b,
|
||||
output reg [3:0] sum
|
||||
);
|
||||
|
||||
always @(*) begin
|
||||
case ({a,b})
|
||||
6'd0: sum=4'd0;
|
||||
6'd1: sum=4'd1;
|
||||
6'd2: sum=4'd2;
|
||||
6'd3: sum=4'd3;
|
||||
6'd4: sum=4'd4;
|
||||
6'd5: sum=4'd5;
|
||||
6'd6: sum=4'd6;
|
||||
6'd7: sum=4'd7;
|
||||
6'd8: sum=4'd1;
|
||||
6'd9: sum=4'd2;
|
||||
6'd10: sum=4'd3;
|
||||
6'd11: sum=4'd4;
|
||||
6'd12: sum=4'd5;
|
||||
6'd13: sum=4'd6;
|
||||
6'd14: sum=4'd7;
|
||||
6'd15: sum=4'd8;
|
||||
6'd16: sum=4'd2;
|
||||
6'd17: sum=4'd3;
|
||||
6'd18: sum=4'd4;
|
||||
6'd19: sum=4'd5;
|
||||
6'd20: sum=4'd6;
|
||||
6'd21: sum=4'd7;
|
||||
6'd22: sum=4'd8;
|
||||
6'd23: sum=4'd9;
|
||||
6'd24: sum=4'd3;
|
||||
6'd25: sum=4'd4;
|
||||
6'd26: sum=4'd5;
|
||||
6'd27: sum=4'd6;
|
||||
6'd28: sum=4'd7;
|
||||
6'd29: sum=4'd8;
|
||||
6'd30: sum=4'd9;
|
||||
6'd31: sum=4'd10;
|
||||
6'd32: sum=4'd4;
|
||||
6'd33: sum=4'd5;
|
||||
6'd34: sum=4'd6;
|
||||
6'd35: sum=4'd7;
|
||||
6'd36: sum=4'd8;
|
||||
6'd37: sum=4'd9;
|
||||
6'd38: sum=4'd10;
|
||||
6'd39: sum=4'd11;
|
||||
6'd40: sum=4'd5;
|
||||
6'd41: sum=4'd6;
|
||||
6'd42: sum=4'd7;
|
||||
6'd43: sum=4'd8;
|
||||
6'd44: sum=4'd9;
|
||||
6'd45: sum=4'd10;
|
||||
6'd46: sum=4'd11;
|
||||
6'd47: sum=4'd12;
|
||||
6'd48: sum=4'd6;
|
||||
6'd49: sum=4'd7;
|
||||
6'd50: sum=4'd8;
|
||||
6'd51: sum=4'd9;
|
||||
6'd52: sum=4'd10;
|
||||
6'd53: sum=4'd11;
|
||||
6'd54: sum=4'd12;
|
||||
6'd55: sum=4'd13;
|
||||
6'd56: sum=4'd7;
|
||||
6'd57: sum=4'd8;
|
||||
6'd58: sum=4'd9;
|
||||
6'd59: sum=4'd10;
|
||||
6'd60: sum=4'd11;
|
||||
6'd61: sum=4'd12;
|
||||
6'd62: sum=4'd13;
|
||||
6'd63: sum=4'd14;
|
||||
default: sum=0;
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
51
Advanced Synthesis Cookbook/arithmetic/sum_of_64.v
Normal file
51
Advanced Synthesis Cookbook/arithmetic/sum_of_64.v
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright 2008 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 09-16-2008
|
||||
// this is essentially a 64 to 7 compressor. The first two
|
||||
// layers are LUT based.
|
||||
//
|
||||
module sum_of_64 (
|
||||
input [63:0] data,
|
||||
output [6:0] sum
|
||||
);
|
||||
|
||||
// first and second layers - LUT based
|
||||
wire [3:0] sum_a,sum_b,sum_c,sum_d,sum_e;
|
||||
wire [2:0] sum_f;
|
||||
twelve_four_comp ca (.data(data[11:0]),.sum(sum_a));
|
||||
twelve_four_comp cb (.data(data[23:12]),.sum(sum_b));
|
||||
twelve_four_comp cc (.data(data[35:24]),.sum(sum_c));
|
||||
twelve_four_comp cd (.data(data[47:36]),.sum(sum_d));
|
||||
twelve_four_comp ce (.data(data[59:48]),.sum(sum_e));
|
||||
six_three_comp cf (.data({2'b0,data[63:60]}),.sum(sum_f));
|
||||
|
||||
// third layer binary adders
|
||||
wire[4:0] sum_g = sum_a + sum_b;
|
||||
wire[4:0] sum_h = sum_c + sum_d;
|
||||
wire[4:0] sum_i = sum_e + sum_f;
|
||||
|
||||
// fourth layer ternary add
|
||||
ternary_add ta (.a(sum_g),.b(sum_h),.c(sum_i),.o(sum));
|
||||
defparam ta .WIDTH=5;
|
||||
|
||||
endmodule
|
42
Advanced Synthesis Cookbook/arithmetic/ternary_add.v
Normal file
42
Advanced Synthesis Cookbook/arithmetic/ternary_add.v
Normal file
@ -0,0 +1,42 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module ternary_add (a,b,c,o);
|
||||
|
||||
parameter WIDTH=8;
|
||||
parameter SIGN_EXT = 1'b0;
|
||||
|
||||
input [WIDTH-1:0] a,b,c;
|
||||
output [WIDTH+1:0] o;
|
||||
wire [WIDTH+1:0] o;
|
||||
|
||||
generate
|
||||
if (!SIGN_EXT)
|
||||
assign o = a+b+c;
|
||||
else
|
||||
assign o = {a[WIDTH-1],a[WIDTH-1],a} +
|
||||
{b[WIDTH-1],b[WIDTH-1],b} +
|
||||
{c[WIDTH-1],c[WIDTH-1],c};
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
74
Advanced Synthesis Cookbook/arithmetic/ternary_sum_nine.v
Normal file
74
Advanced Synthesis Cookbook/arithmetic/ternary_sum_nine.v
Normal file
@ -0,0 +1,74 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 02-16-2006
|
||||
|
||||
// placing the ternary add in a sub module
|
||||
// is not strictly necessary, but makes the
|
||||
// grouping clear and unambiguous if you
|
||||
// want to remove the pipeline registers.
|
||||
|
||||
module tern_node (clk,a,b,c,o);
|
||||
parameter WIDTH = 8;
|
||||
input clk;
|
||||
input [WIDTH-1:0] a;
|
||||
input [WIDTH-1:0] b;
|
||||
input [WIDTH-1:0] c;
|
||||
output [WIDTH+2-1:0] o;
|
||||
reg [WIDTH+2-1:0] o;
|
||||
|
||||
always @(posedge clk) begin
|
||||
o <= a+b+c;
|
||||
end
|
||||
endmodule
|
||||
|
||||
//
|
||||
// pipelined sum of 9 binary words using
|
||||
// 4 ternary adder chains.
|
||||
// This WIDTH 8 example should use 42 DFF and 42
|
||||
// arithmetic logic cells. This would require roughly
|
||||
// 80 arithmetic cells on a binary adder device.
|
||||
//
|
||||
|
||||
module ternary_sum_nine (clk,a,b,c,d,e,f,g,h,i,out);
|
||||
|
||||
parameter WIDTH = 8;
|
||||
|
||||
input clk;
|
||||
input [WIDTH-1:0] a,b,c,d,e,f,g,h,i;
|
||||
output [WIDTH+4-1:0] out;
|
||||
|
||||
wire [WIDTH+2-1:0] part0,part1,part2;
|
||||
|
||||
// entry layer, 9 => 3
|
||||
tern_node x (.clk(clk),.a(a),.b(b),.c(c),.o(part0));
|
||||
defparam x .WIDTH = WIDTH;
|
||||
tern_node y (.clk(clk),.a(d),.b(e),.c(f),.o(part1));
|
||||
defparam y .WIDTH = WIDTH;
|
||||
tern_node z (.clk(clk),.a(g),.b(h),.c(i),.o(part2));
|
||||
defparam z .WIDTH = WIDTH;
|
||||
|
||||
// output layer 3=> 1
|
||||
tern_node o (.clk(clk),.a(part0),.b(part1),.c(part2),.o(out));
|
||||
defparam o .WIDTH = WIDTH+2;
|
||||
|
||||
endmodule
|
61
Advanced Synthesis Cookbook/arithmetic/thirtysix_six_comp.v
Normal file
61
Advanced Synthesis Cookbook/arithmetic/thirtysix_six_comp.v
Normal file
@ -0,0 +1,61 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 2-13-2006
|
||||
// compute sum of 36 bit lines
|
||||
//
|
||||
// uses nine 6:3 compressors = 27 six-luts
|
||||
// plus a 5 bit carry propagate output adder (one bit falls through)
|
||||
|
||||
module thirtysix_six_comp (data,sum);
|
||||
|
||||
input [35:0] data;
|
||||
output [5:0] sum;
|
||||
wire [5:0] sum;
|
||||
|
||||
wire [5:0] word_l;
|
||||
wire [5:0] word_m;
|
||||
wire [5:0] word_h;
|
||||
|
||||
wire [2:0] sa,sb,sc,sd,se,sf;
|
||||
wire [2:0] slo,sme,shi;
|
||||
|
||||
six_three_comp a (.data(data[5:0]),.sum(sa));
|
||||
six_three_comp b (.data(data[11:6]),.sum(sb));
|
||||
six_three_comp c (.data(data[17:12]),.sum(sc));
|
||||
six_three_comp d (.data(data[23:18]),.sum(sd));
|
||||
six_three_comp e (.data(data[29:24]),.sum(se));
|
||||
six_three_comp f (.data(data[35:30]),.sum(sf));
|
||||
|
||||
six_three_comp lo (.data({sa[0],sb[0],sc[0],sd[0],se[0],sf[0]}),.sum(slo));
|
||||
six_three_comp me (.data({sa[1],sb[1],sc[1],sd[1],se[1],sf[1]}),.sum(sme));
|
||||
six_three_comp hi (.data({sa[2],sb[2],sc[2],sd[2],se[2],sf[2]}),.sum(shi));
|
||||
|
||||
wire [7:0] tmp_sum;
|
||||
ternary_add t (.a({3'b0,slo}),
|
||||
.b({2'b0,sme,1'b0}),
|
||||
.c({1'b0,shi,2'b0}),
|
||||
.o(tmp_sum));
|
||||
defparam t .WIDTH = 6;
|
||||
assign sum = tmp_sum[5:0];
|
||||
|
||||
endmodule
|
48
Advanced Synthesis Cookbook/arithmetic/three_two_comp.v
Normal file
48
Advanced Synthesis Cookbook/arithmetic/three_two_comp.v
Normal file
@ -0,0 +1,48 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 02-13-2006
|
||||
//
|
||||
// Three input two output compressor (full adder)
|
||||
// area cost is two 3-LUTs.
|
||||
|
||||
module three_two_comp (data,sum);
|
||||
|
||||
input [2:0] data;
|
||||
output [1:0] sum;
|
||||
|
||||
reg [1:0] sum;
|
||||
|
||||
always @(data) begin
|
||||
case (data)
|
||||
0: sum=0;
|
||||
1: sum=1;
|
||||
2: sum=1;
|
||||
3: sum=2;
|
||||
4: sum=1;
|
||||
5: sum=2;
|
||||
6: sum=2;
|
||||
7: sum=3;
|
||||
default: sum=0;
|
||||
endcase
|
||||
end
|
||||
endmodule
|
38
Advanced Synthesis Cookbook/arithmetic/twelve_four_comp.v
Normal file
38
Advanced Synthesis Cookbook/arithmetic/twelve_four_comp.v
Normal file
@ -0,0 +1,38 @@
|
||||
// Copyright 2008 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler -09-15-2008
|
||||
// This is intended to use exactly ten LUTs in two levels.
|
||||
|
||||
module twelve_four_comp (data,sum);
|
||||
|
||||
input [11:0] data;
|
||||
output [3:0] sum;
|
||||
|
||||
wire [3:0] sum /* synthesis keep */;
|
||||
wire [2:0] sum_a,sum_b;
|
||||
|
||||
six_three_comp ca (.data(data[5:0]),.sum(sum_a));
|
||||
six_three_comp cb (.data(data[11:6]),.sum(sum_b));
|
||||
sum_of_3bit_pair st (.a(sum_a),.b(sum_b),.sum(sum));
|
||||
|
||||
endmodule
|
106
Advanced Synthesis Cookbook/arithmetic/wide_compress.v
Normal file
106
Advanced Synthesis Cookbook/arithmetic/wide_compress.v
Normal file
@ -0,0 +1,106 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
// baeckler - 03-14-2006
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// wide 3:2 compressor
|
||||
////////////////////////////////////////////////////////
|
||||
module compress_32 (a,b,c,oo,ot);
|
||||
parameter WIDTH = 16;
|
||||
input [WIDTH-1:0] a,b,c;
|
||||
output [WIDTH-1:0] oo,ot;
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for (i=0; i<WIDTH; i=i+1)
|
||||
begin : cmp
|
||||
assign oo[i] = a[i] ^ b[i] ^ c[i];
|
||||
assign ot[i] = (a[i] & b[i]) | (a[i] & c[i]) | (b[i] & c[i]);
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
// wide 4:2 compressor (with cin and cout)
|
||||
// the carry signal cannot ripple through more than one
|
||||
// stage.
|
||||
////////////////////////////////////////////////////////
|
||||
module compress_42 (ci,a,b,c,d,co,oo,ot);
|
||||
parameter WIDTH = 16;
|
||||
input ci;
|
||||
input [WIDTH-1:0] a,b,c,d;
|
||||
output [WIDTH-1:0] oo,ot;
|
||||
output co;
|
||||
|
||||
wire [WIDTH-1:0] internal_o;
|
||||
wire [WIDTH-1:0] internal_t;
|
||||
|
||||
compress_32 i (.a(a),.b(b),.c(c),.oo(internal_o),.ot(internal_t));
|
||||
defparam i .WIDTH = WIDTH;
|
||||
|
||||
compress_32 o (.a({internal_t[WIDTH-2:0],ci}),
|
||||
.b(d),
|
||||
.c(internal_o),
|
||||
.oo(oo),.ot(ot));
|
||||
defparam o .WIDTH = WIDTH;
|
||||
assign co = internal_t[WIDTH-1];
|
||||
endmodule
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
// Quick sanity check
|
||||
////////////////////////////////////////////////////////
|
||||
module compress_test ();
|
||||
|
||||
parameter WIDTH = 16;
|
||||
|
||||
reg fail;
|
||||
reg [WIDTH-1:0] a,b,c,d;
|
||||
wire [WIDTH+2-1:0] out_x, out_y;
|
||||
|
||||
assign out_x = a + b + c + d;
|
||||
|
||||
wire [WIDTH-1:0] oo,ot;
|
||||
wire co;
|
||||
compress_42 cmp (.ci(1'b0),.a(a),.b(b),.c(c),.d(d),.co(co),.oo(oo),.ot(ot));
|
||||
defparam cmp .WIDTH = WIDTH;
|
||||
|
||||
assign out_y = {co,oo} + (ot<<1);
|
||||
|
||||
initial begin
|
||||
a = 0; b = 0; c = 0; d = 0;
|
||||
fail = 0;
|
||||
#10000
|
||||
if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
always begin
|
||||
#50 a = $random; b = $random; c = $random; d = $random;
|
||||
#50 if (out_x !== out_y) begin
|
||||
fail = 1;
|
||||
$display ("Mismatch at time %d",$time);
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
414
Advanced Synthesis Cookbook/communication/decoder_8b10b.v
Normal file
414
Advanced Synthesis Cookbook/communication/decoder_8b10b.v
Normal file
@ -0,0 +1,414 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 04-10-2006
|
||||
// an 8b10b decoder, based on files from Martin R and IBM paper
|
||||
|
||||
module decoder_8b10b (
|
||||
clk,
|
||||
rst,
|
||||
din_ena, // 10b data ready
|
||||
din_dat, // 10b data input
|
||||
din_rd, // running disparity input
|
||||
dout_val, // data out valid
|
||||
dout_dat, // data out
|
||||
dout_k, // special code
|
||||
dout_kerr, // coding mistake detected
|
||||
dout_rderr, // running disparity mistake detected
|
||||
dout_rdcomb, // running disparity output (comb)
|
||||
dout_rdreg // running disparity output (reg)
|
||||
);
|
||||
|
||||
parameter RDERR = 1;
|
||||
parameter KERR = 1;
|
||||
|
||||
// method = 0 is generic for comparison / test
|
||||
// method = 1 is speed optimized
|
||||
parameter METHOD = 1;
|
||||
|
||||
input clk;
|
||||
input rst;
|
||||
input din_ena;
|
||||
input [9:0] din_dat;
|
||||
input din_rd;
|
||||
output dout_val;
|
||||
output[7:0] dout_dat;
|
||||
output dout_k;
|
||||
output dout_kerr;
|
||||
output dout_rderr;
|
||||
output dout_rdcomb;
|
||||
output dout_rdreg;
|
||||
|
||||
//reg [9:0] din_dat;
|
||||
|
||||
reg dout_val;
|
||||
reg [7:0] dout_dat;
|
||||
reg dout_k;
|
||||
reg dout_kerr;
|
||||
reg dout_rderr;
|
||||
reg dout_rdreg;
|
||||
|
||||
wire a = din_dat[0];
|
||||
wire b = din_dat[1];
|
||||
wire c = din_dat[2];
|
||||
wire d = din_dat[3];
|
||||
wire e = din_dat[4];
|
||||
wire i = din_dat[5];
|
||||
wire f = din_dat[6];
|
||||
wire g = din_dat[7];
|
||||
wire h = din_dat[8];
|
||||
wire j = din_dat[9];
|
||||
|
||||
|
||||
//classification
|
||||
wire P04 = (!a & !b & !c & !d);
|
||||
wire P13 = (!a & !b & !c & d) | (!a & !b & c & !d) | (!a & b & !c & !d) | (a & !b & !c & !d);
|
||||
wire P22 = (!a & !b & c & d) | (!a & b & c & !d) | (a & b & !c & !d) | (a & !b & c & !d) | (a & !b & !c & d) | (!a & b & !c & d);
|
||||
wire P31 = (a & b & c & !d) | (a & b & !c & d) | (a & !b & c & d) | (!a & b & c & d);
|
||||
wire P40 = (a & b & c & d);
|
||||
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// data outputs
|
||||
////////////////////////////////////////////////
|
||||
|
||||
wire A = (P22 & !b & !c & !(e^i)) ? !a :
|
||||
(P31 & i) ? !a :
|
||||
(P13 & d & e & i) ? !a :
|
||||
(P22 & !a & !c & !(e^i)) ? !a :
|
||||
(P13 & !e) ? !a :
|
||||
(a & b & e & i) ? !a :
|
||||
(!c & !d & !e & !i) ? !a :
|
||||
a;
|
||||
wire B = (P22 & b & c & !(e^i)) ? !b :
|
||||
(P31 & i) ? !b :
|
||||
(P13 & d & e & i) ? !b :
|
||||
(P22 & a & c & !(e^i)) ? !b :
|
||||
(P13 & !e) ? !b :
|
||||
(a & b & e & i) ? !b :
|
||||
(!c & !d & !e & !i) ? !b :
|
||||
b;
|
||||
wire C = (P22 & b & c & !(e^i)) ? !c :
|
||||
(P31 & i) ? !c :
|
||||
(P13 & d & e & i) ? !c :
|
||||
(P22 & !a & !c & !(e^i)) ? !c :
|
||||
(P13 & !e) ? !c :
|
||||
(!a & !b & !e & !i) ? !c :
|
||||
(!c & !d & !e & !i) ? !c :
|
||||
c;
|
||||
wire D = (P22 & !b & !c & !(e^i)) ? !d :
|
||||
(P31 & i) ? !d :
|
||||
(P13 & d & e & i) ? !d :
|
||||
(P22 & a & c & !(e^i)) ? !d :
|
||||
(P13 & !e) ? !d :
|
||||
(a & b & e & i) ? !d :
|
||||
(!c & !d & !e & !i) ? !d :
|
||||
d;
|
||||
wire E = (P22 & !b & !c & !(e^i)) ? !e :
|
||||
(P13 & !i) ? !e :
|
||||
(P13 & d & e & i) ? !e :
|
||||
(P22 & !a & !c & !(e^i)) ? !e :
|
||||
(P13 & !e) ? !e :
|
||||
(!a & !b & !e & !i) ? !e :
|
||||
(!c & !d & !e & !i) ? !e :
|
||||
e;
|
||||
|
||||
|
||||
wire F = (f & h & j) ? !f :
|
||||
(!c & !d & !e & !i & (h^j)) ? !f :
|
||||
(!f & !g & h & j) ? !f :
|
||||
(f & g & j) ? !f :
|
||||
(!f & !g & !h) ? !f :
|
||||
(g & h & j) ? !f :
|
||||
f;
|
||||
wire G = (!f & !h & !j) ? !g :
|
||||
(!c & !d & !e & !i & (h^j)) ? !g :
|
||||
(!f & !g & h & j) ? !g :
|
||||
(f & g & j) ? !g :
|
||||
(!f & !g & !h) ? !g :
|
||||
(!g & !h & !j) ? !g :
|
||||
g;
|
||||
wire H = (f & h & j) ? !h :
|
||||
(!c & !d & !e & !i & (h^j)) ? !h :
|
||||
(!f & !g & h & j) ? !h :
|
||||
(f & g & j) ? !h :
|
||||
(!f & !g & !h) ? !h :
|
||||
(!g & !h & !j) ? !h :
|
||||
h;
|
||||
|
||||
|
||||
wire K = (c & d & e & i) |
|
||||
(!c & !d & !e & !i) |
|
||||
(P13 & !e & i & g & h & j) |
|
||||
(P31 & e & !i & !g & !h & !j);
|
||||
|
||||
|
||||
////////////////////////////////////////////////
|
||||
//running disparity - generate and err check
|
||||
////////////////////////////////////////////////
|
||||
wire rd1n = (P04) ? 1 :
|
||||
(P13 & !(e & i)) ? 1 :
|
||||
(P22 & !e & !i) ? 1 :
|
||||
(P13 & d & e & i) ? 1 :
|
||||
0 /* synthesis keep */;
|
||||
wire rd1p = (P40) ? 1 :
|
||||
(P31 & !(!e & !i)) ? 1 :
|
||||
(P22 & e & i) ? 1 :
|
||||
(P31 & !d & !e & !i) ? 1 :
|
||||
0 /* synthesis keep */;
|
||||
wire rd1e = (P13 & !d & e & i) ? 1 :
|
||||
(P22 & (e ^ i)) ? 1 :
|
||||
(P31 & d & !e & !i) ? 1 :
|
||||
0 /* synthesis keep */;
|
||||
|
||||
wire rd1_err = (!din_rd & rd1n) | (din_rd & rd1p);
|
||||
|
||||
/////////////////////////////
|
||||
// factored rd1 generation
|
||||
/////////////////////////////
|
||||
wire [63:0] rd1_when_din_rd_0_mask = 64'hffe8e880e8808000;
|
||||
wire rd1_when_din_rd_0 = rd1_when_din_rd_0_mask[din_dat[5:0]] /* synthesis keep */;
|
||||
wire [63:0] rd1_when_din_rd_1_mask = 64'hfffefee8fee8e800;
|
||||
wire rd1_when_din_rd_1 = rd1_when_din_rd_1_mask[din_dat[5:0]] /* synthesis keep */;
|
||||
wire rd1 = din_rd ? rd1_when_din_rd_1 : rd1_when_din_rd_0;
|
||||
|
||||
wire rd2n = (!f & !g & !h) ? 1 :
|
||||
(!f & !g & !j) ? 1 :
|
||||
(!f & !h & !j) ? 1 :
|
||||
(!g & !h & !j) ? 1 :
|
||||
(!f & !g & h & j) ? 1 :
|
||||
0 /* synthesis keep */;
|
||||
wire rd2p = (f & g & h) ? 1 :
|
||||
(f & g & j) ? 1 :
|
||||
(f & h & j) ? 1 :
|
||||
(g & h & j) ? 1 :
|
||||
(f & g & !h & !j) ? 1 :
|
||||
0 /* synthesis keep */;
|
||||
wire rd2e = ((f ^ g) & (h ^ j)) ? 1 :
|
||||
0;
|
||||
|
||||
wire rd2_err = (!rd1 & rd2n) | (rd1 & rd2p);
|
||||
|
||||
|
||||
// these two conditions appear in rd2p and rd2n with the
|
||||
// opposite associated rdcomb output.
|
||||
wire dout_rdcomb_special = (!f & !g & h & j) |
|
||||
( f & g & !h & !j) /* synthesis keep */;
|
||||
|
||||
wire dout_rdcomb = (rd2p) ? !dout_rdcomb_special :
|
||||
(rd2n) ? dout_rdcomb_special :
|
||||
rd1;
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// K error check - this is by far the most
|
||||
// complex expression in the decoder.
|
||||
// It appears to require depth 3. Please let
|
||||
// me know if you identify a depth 2 mapping.
|
||||
////////////////////////////////////////////////
|
||||
wire k_err;
|
||||
generate
|
||||
if (METHOD == 0) begin
|
||||
|
||||
assign k_err = //5b6b errors
|
||||
(P04) ? 1 :
|
||||
(P13 & !e & !i) ? 1 :
|
||||
(P31 & e & i) ? 1 :
|
||||
(P40) ? 1 :
|
||||
//3b4b errors
|
||||
( f & g & h & j) ? 1 :
|
||||
(!f & !g & !h & !j) ? 1 :
|
||||
|
||||
//any 2nd phase rd error, except if rd1 is even
|
||||
(rd2_err & !rd1e) ? 1 :
|
||||
|
||||
// + some odd ones, dx.7 - specials ...
|
||||
// d11.7,d13.7,d14.7,d17.7,d18.7,d20.7 use 1000/0111
|
||||
// k23.7,k27.7,k29.7,k30.7 are legal use 1000/0111
|
||||
// other x.7 use 0001/1110
|
||||
|
||||
// P22 & xxxx01 1110 - ok, d12.7
|
||||
// P22 & xxxx10 1110 - ok, d28.7
|
||||
// P22 & 011000 1110 - ok, d0.7
|
||||
// P22 & 101000 1110 - ok, d15.7
|
||||
// P22 & 100100 1110 - ok, d16.7
|
||||
// P22 & 001100 1110 - ok, d24.7
|
||||
// P22 & 010100 1110 - ok, d31.7
|
||||
// P22 & 110000 1110 - illegal
|
||||
// xxxx11 1110 - illegal
|
||||
( a & b & !c & !d & !e & !i & f & g & h & !j) ? 1 :
|
||||
( e & i & f & g & h & !j) ? 1 :
|
||||
|
||||
// P22 & xxxx01 0001 - ok, d6.7
|
||||
// P31 & xxxx01 0001 - ok, d1.7
|
||||
// P31 & xxxx10 0001 - ok, d23.7
|
||||
// P22 & xxxx10 0001 - ok, d19.7
|
||||
// P13 & xxxx11 0001 - ok, d7.7
|
||||
// 110011 0001 - ok, d24.7
|
||||
// 101011 0001 - ok, d31.7
|
||||
// 011011 0001 - ok, d16.7
|
||||
// 100111 0001 - ok, d0.7
|
||||
// 010111 0001 - ok, d15.7
|
||||
// 001111 0001 - illegal
|
||||
// xxxx00 0001 - illegal
|
||||
(!a & !b & c & d & e & i & !f & !g & !h & j) ? 1 :
|
||||
( !e & !i & !f & !g & !h & j) ? 1 :
|
||||
|
||||
// 110000 0111 - ok, k28.7
|
||||
// P13 & xxxx01 0111 = ok, kxx.7
|
||||
// 100011 0111 = ok, d17.7
|
||||
// 010011 0111 = ok, d18.7
|
||||
// 001011 0111 = ok, d20.7
|
||||
// 000111 0111 = illegal (rderr)
|
||||
// else xxxxxx 0111 - illegal
|
||||
(!(P22 & !c & !d) & !e & !i & !f & g & h & j) ? 1 :
|
||||
(!(P13) & !e & i & !f & g & h & j) ? 1 :
|
||||
(!(P13 & (a | b | c)) & e & i & !f & g & h & j) ? 1 :
|
||||
( e & !i & !f & g & h & j) ? 1 :
|
||||
|
||||
// 001111 1000 - ok, k28.7
|
||||
// P31 & xxxx10 1000 = ok, kxx.7
|
||||
// 110100 1000 - ok, d11.7
|
||||
// 101100 1000 - ok, d13.7
|
||||
// 011100 1000 - ok, d14.7
|
||||
// 111000 1000 - illegal (rderr)
|
||||
// else xxxxxx 1000 - illegal
|
||||
(!(P22 & c & d) & e & i & f & !g & !h & !j) ? 1 :
|
||||
(!(P31) & e & !i & f & !g & !h & !j) ? 1 :
|
||||
(!(P31 & (!a | !b | !c)) & !e & !i & f & !g & !h & !j) ? 1 :
|
||||
( !e & i & f & !g & !h & !j) ? 1 :
|
||||
|
||||
0;
|
||||
end
|
||||
else if (METHOD == 1) begin
|
||||
/////////////////////////////////////
|
||||
// use the upper and lower portions only
|
||||
// to identify definite errors
|
||||
/////////////////////////////////////
|
||||
wire [63:0] kerr_mask_ai = 64'h6881800180018117;
|
||||
wire [63:0] kerr_mask_ej = 64'hf20000018000004f;
|
||||
wire kerr_out_ai = kerr_mask_ai[din_dat[5:0]] /* synthesis keep */;
|
||||
wire kerr_out_ej = kerr_mask_ej[din_dat[9:4]] /* synthesis keep */;
|
||||
wire rd2_err_lc = rd2_err /* synthesis keep */;
|
||||
|
||||
wire kerr6,kerr7,kerr8,kerr9,kerr_remainder;
|
||||
stratixii_lcell_comb kerr6_I (
|
||||
.datab(!din_dat[7]),
|
||||
.datac(!din_dat[6]),
|
||||
.datad(!din_dat[8]),
|
||||
.datae(!din_dat[9]),
|
||||
.dataa(1'b1),.dataf(1'b1),.datag(1'b1),
|
||||
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
|
||||
.combout(kerr6 ));
|
||||
defparam kerr6_I .shared_arith = "off";
|
||||
defparam kerr6_I .extended_lut = "off";
|
||||
defparam kerr6_I .lut_mask = 64'h0C0000300C000030;
|
||||
|
||||
stratixii_lcell_comb kerr7_I (
|
||||
.dataa(!din_dat[3]),
|
||||
.datab(!din_dat[7]),
|
||||
.datac(!din_dat[6]),
|
||||
.datad(!din_dat[8]),
|
||||
.datae(!din_dat[9]),
|
||||
.dataf(1'b1),.datag(1'b1),
|
||||
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
|
||||
.combout(kerr7 ));
|
||||
defparam kerr7_I .shared_arith = "off";
|
||||
defparam kerr7_I .extended_lut = "off";
|
||||
defparam kerr7_I .lut_mask = 64'h0002403000024030;
|
||||
|
||||
stratixii_lcell_comb kerr8_I (
|
||||
.dataa(!din_dat[0]),
|
||||
.datab(!din_dat[1]),
|
||||
.datac(!din_dat[2]),
|
||||
.datad(!din_dat[4]),
|
||||
.datae(!din_dat[3]),
|
||||
.dataf(1'b1),.datag(1'b1),
|
||||
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
|
||||
.combout(kerr8 ));
|
||||
defparam kerr8_I .shared_arith = "off";
|
||||
defparam kerr8_I .extended_lut = "off";
|
||||
defparam kerr8_I .lut_mask = 64'h6868960868689608;
|
||||
|
||||
stratixii_lcell_comb kerr9_I (
|
||||
.dataa(!din_dat[0]),
|
||||
.datab(!din_dat[1]),
|
||||
.datac(!din_dat[2]),
|
||||
.datad(!din_dat[4]),
|
||||
.datae(!din_dat[3]),
|
||||
.dataf(1'b1),.datag(1'b1),
|
||||
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
|
||||
.combout(kerr9 ));
|
||||
defparam kerr9_I .shared_arith = "off";
|
||||
defparam kerr9_I .extended_lut = "off";
|
||||
defparam kerr9_I .lut_mask = 64'h1001161E1001161E;
|
||||
|
||||
stratixii_lcell_comb kerr_rem_I (
|
||||
.dataa(!din_dat[5]),
|
||||
.datab(!kerr6 ),
|
||||
.datac(!kerr7 ),
|
||||
.datad(!din_dat[4]),
|
||||
.datae(!kerr8 ),
|
||||
.dataf(!kerr9 ),
|
||||
.datag(1'b1),
|
||||
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
|
||||
.combout(kerr_remainder ));
|
||||
defparam kerr_rem_I .shared_arith = "off";
|
||||
defparam kerr_rem_I .extended_lut = "off";
|
||||
defparam kerr_rem_I .lut_mask = 64'h2331223029110325;
|
||||
|
||||
assign k_err = kerr_out_ai | kerr_out_ej |
|
||||
rd2_err_lc & !rd1e |
|
||||
kerr_remainder;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// output registers
|
||||
////////////////////////////////////////////////
|
||||
always @(posedge clk or posedge rst)
|
||||
begin
|
||||
if (rst)
|
||||
begin
|
||||
dout_k <= 0;
|
||||
dout_val <= 0;
|
||||
dout_dat <= 0;
|
||||
dout_rdreg <= 0;
|
||||
dout_rderr <= 0;
|
||||
dout_kerr <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
dout_val <= 0;
|
||||
if (din_ena)
|
||||
begin
|
||||
dout_k <= K;
|
||||
dout_val <= din_ena;
|
||||
dout_dat <= {H,G,F,E,D,C,B,A};
|
||||
dout_rdreg <= dout_rdcomb;
|
||||
dout_rderr <= (RDERR) ? (rd1_err | rd2_err) : 0;
|
||||
dout_kerr <= (KERR) ? k_err : 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
60
Advanced Synthesis Cookbook/communication/descrambler.v
Normal file
60
Advanced Synthesis Cookbook/communication/descrambler.v
Normal file
@ -0,0 +1,60 @@
|
||||
// Copyright 2011 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`timescale 1 ps / 1 ps
|
||||
|
||||
// baeckler - 12-17-2008
|
||||
// Unrolled descrambler LFSR
|
||||
|
||||
module descrambler # (
|
||||
parameter WIDTH = 512
|
||||
)(
|
||||
input clk,arst,ena,
|
||||
input [WIDTH-1:0] din, // bit 0 is used first
|
||||
output reg [WIDTH-1:0] dout
|
||||
);
|
||||
|
||||
reg [57:0] scram_state;
|
||||
wire [WIDTH+58-1:0] history;
|
||||
wire [WIDTH-1:0] dout_w;
|
||||
assign history = {din,scram_state};
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for (i=0; i<WIDTH; i=i+1) begin : lp
|
||||
assign dout_w[i] = history[58+i-58] ^ history[58+i-39] ^ history[58+i];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
dout <= 0;
|
||||
scram_state <= 58'h3ff_ffff_ffff_ffff;
|
||||
end
|
||||
else if (ena) begin
|
||||
dout <= dout_w;
|
||||
scram_state <= history[WIDTH+58-1:WIDTH];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
505
Advanced Synthesis Cookbook/communication/encoder_8b10b.v
Normal file
505
Advanced Synthesis Cookbook/communication/encoder_8b10b.v
Normal file
@ -0,0 +1,505 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 04-10-2006
|
||||
// an 8b10b encoder, based on files from Martin R and IBM paper
|
||||
|
||||
module encoder_8b10b (
|
||||
clk,
|
||||
rst,
|
||||
kin_ena, // Data in is a special code, not all are legal.
|
||||
ein_ena, // Data (or code) input enable
|
||||
ein_dat, // 8b data in
|
||||
ein_rd, // running disparity input
|
||||
eout_val, // data out is valid
|
||||
eout_dat, // data out
|
||||
eout_rdcomb, // running disparity output (comb)
|
||||
eout_rdreg // running disparity output (reg)
|
||||
);
|
||||
|
||||
// method = 0 is generic for comparison / test
|
||||
// method = 1 is speed optimized
|
||||
|
||||
parameter METHOD = 1;
|
||||
|
||||
input clk;
|
||||
input rst;
|
||||
input kin_ena;
|
||||
input ein_ena;
|
||||
input [7:0] ein_dat;
|
||||
input ein_rd;
|
||||
output eout_val;
|
||||
output[9:0] eout_dat;
|
||||
output eout_rdcomb;
|
||||
output eout_rdreg;
|
||||
|
||||
wire ein_rd;
|
||||
wire ein_ena;
|
||||
wire [7:0] ein_dat;
|
||||
reg eout_val;
|
||||
reg [9:0] eout_dat;
|
||||
|
||||
wire A = ein_dat[0];
|
||||
wire B = ein_dat[1];
|
||||
wire C = ein_dat[2];
|
||||
wire D = ein_dat[3];
|
||||
wire E = ein_dat[4];
|
||||
wire F = ein_dat[5];
|
||||
wire G = ein_dat[6];
|
||||
wire H = ein_dat[7];
|
||||
wire K = kin_ena;
|
||||
|
||||
reg rd1_part /* synthesis keep */;
|
||||
reg rd1;
|
||||
|
||||
reg eout_rdcomb;
|
||||
reg eout_rdreg;
|
||||
reg SorK;
|
||||
reg a,b,c,d,e,f,g,h,i,j;
|
||||
|
||||
generate
|
||||
if (METHOD == 0) begin
|
||||
//classification
|
||||
wire L04 = (!A & !B & !C & !D);
|
||||
wire L13 = (!A & !B & !C & D) | (!A & !B & C & !D) | (!A & B & !C & !D) | (A & !B & !C & !D);
|
||||
wire L22 = (!A & !B & C & D) | (!A & B & C & !D) | (A & B & !C & !D) | (A & !B & C & !D) | (A & !B & !C & D) | (!A & B & !C & D);
|
||||
wire L31 = (A & B & C & !D) | (A & B & !C & D) | (A & !B & C & D) | (!A & B & C & D);
|
||||
wire L40 = (A & B & C & D);
|
||||
|
||||
wire disp0 = (!L22 & !L31 & !E);
|
||||
wire disp1 = (L31 & !D & !E);
|
||||
wire disp2 = (L13 & D & E);
|
||||
wire disp3 = (!L22 & !L13 & E);
|
||||
wire invert_ai = !(ein_rd ? (disp3 | disp1 | K) : (disp0 | disp2));
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
a = !A ^ invert_ai;
|
||||
b = ((L04) ? 0 : (L40) ? 1 :!B) ^ invert_ai;
|
||||
c = ((L04) ? 0 : (L13 & D & E) ? 0 : !C) ^ invert_ai;
|
||||
d = ((L40) ? 1 : !D) ^ invert_ai;
|
||||
e = ((L13 & !E) ? 0 : (L13 & D & E) ? 1 : !E) ^ invert_ai;
|
||||
i = ((L22 & !E) ? 0 : (L04 & E) ? 0 : (L13 & !D & E) ? 0 :
|
||||
(L40 & E) ? 0 : (L22 & K) ? 0 : 1) ^ invert_ai;
|
||||
|
||||
rd1_part = (disp0 | disp2 | disp3);
|
||||
rd1 = (rd1_part | K) ^ ein_rd;
|
||||
end
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
SorK = ( e & i & !rd1) | (!e & !i & rd1) | K;
|
||||
end
|
||||
|
||||
wire disp4 = (!F & !G);
|
||||
wire disp5 = (F & G);
|
||||
wire disp6 = ((F ^ G) & K);
|
||||
wire invert_fj = !(rd1 ? disp5 : (disp4 | disp6));
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
f = ((F & G & H & (SorK)) ? 1 : !F) ^ invert_fj;
|
||||
g = ((!F & !G & !H) ? 0 : !G) ^ invert_fj;
|
||||
h = (!H) ^ invert_fj;
|
||||
j = (((F ^ G) & !H) ? 0 : (F & G & H & (SorK)) ? 0 : 1) ^ invert_fj;
|
||||
eout_rdcomb = (disp4 | (F & G & H)) ^ rd1;
|
||||
end
|
||||
end
|
||||
else if (METHOD == 1) begin
|
||||
wire rdout_x,rdout_y;
|
||||
|
||||
stratixii_lcell_comb rdoutx (
|
||||
.dataa (!B),.datab (!D),.datac (!E),.datad (!A),.datae (!C),.dataf (!K),.datag(1'b1),
|
||||
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
|
||||
.combout(rdout_x));
|
||||
defparam rdoutx .lut_mask = 64'h157E7EE800000000;
|
||||
defparam rdoutx .shared_arith = "off";
|
||||
defparam rdoutx .extended_lut = "off";
|
||||
|
||||
stratixii_lcell_comb rdouty (
|
||||
.dataa (!H),.datab (!ein_rd),.datac (!F),.datad (!G),.datae (!rdout_x),.dataf (!rdout_x),.datag(1'b1),
|
||||
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
|
||||
.combout(rdout_y));
|
||||
defparam rdouty .lut_mask = 64'h3CC99663699CC336;
|
||||
defparam rdouty .shared_arith = "off";
|
||||
defparam rdouty .extended_lut = "off";
|
||||
|
||||
always @(*) begin
|
||||
eout_rdcomb = rdout_y;
|
||||
|
||||
case ({ein_rd,ein_dat[4:0],kin_ena})
|
||||
7'h00 : {i,e,d,c,b,a} = 6'h39;
|
||||
7'h01 : {i,e,d,c,b,a} = 6'h39;
|
||||
7'h02 : {i,e,d,c,b,a} = 6'h2e;
|
||||
7'h03 : {i,e,d,c,b,a} = 6'h2e;
|
||||
7'h04 : {i,e,d,c,b,a} = 6'h2d;
|
||||
7'h05 : {i,e,d,c,b,a} = 6'h2d;
|
||||
7'h06 : {i,e,d,c,b,a} = 6'h23;
|
||||
7'h07 : {i,e,d,c,b,a} = 6'h23;
|
||||
7'h08 : {i,e,d,c,b,a} = 6'h2b;
|
||||
7'h09 : {i,e,d,c,b,a} = 6'h2b;
|
||||
7'h0a : {i,e,d,c,b,a} = 6'h25;
|
||||
7'h0b : {i,e,d,c,b,a} = 6'h25;
|
||||
7'h0c : {i,e,d,c,b,a} = 6'h26;
|
||||
7'h0d : {i,e,d,c,b,a} = 6'h26;
|
||||
7'h0e : {i,e,d,c,b,a} = 6'h07;
|
||||
7'h0f : {i,e,d,c,b,a} = 6'h07;
|
||||
7'h10 : {i,e,d,c,b,a} = 6'h27;
|
||||
7'h11 : {i,e,d,c,b,a} = 6'h27;
|
||||
7'h12 : {i,e,d,c,b,a} = 6'h29;
|
||||
7'h13 : {i,e,d,c,b,a} = 6'h29;
|
||||
7'h14 : {i,e,d,c,b,a} = 6'h2a;
|
||||
7'h15 : {i,e,d,c,b,a} = 6'h2a;
|
||||
7'h16 : {i,e,d,c,b,a} = 6'h0b;
|
||||
7'h17 : {i,e,d,c,b,a} = 6'h0b;
|
||||
7'h18 : {i,e,d,c,b,a} = 6'h2c;
|
||||
7'h19 : {i,e,d,c,b,a} = 6'h2c;
|
||||
7'h1a : {i,e,d,c,b,a} = 6'h0d;
|
||||
7'h1b : {i,e,d,c,b,a} = 6'h0d;
|
||||
7'h1c : {i,e,d,c,b,a} = 6'h0e;
|
||||
7'h1d : {i,e,d,c,b,a} = 6'h0e;
|
||||
7'h1e : {i,e,d,c,b,a} = 6'h3a;
|
||||
7'h1f : {i,e,d,c,b,a} = 6'h3a;
|
||||
7'h20 : {i,e,d,c,b,a} = 6'h36;
|
||||
7'h21 : {i,e,d,c,b,a} = 6'h36;
|
||||
7'h22 : {i,e,d,c,b,a} = 6'h31;
|
||||
7'h23 : {i,e,d,c,b,a} = 6'h31;
|
||||
7'h24 : {i,e,d,c,b,a} = 6'h32;
|
||||
7'h25 : {i,e,d,c,b,a} = 6'h32;
|
||||
7'h26 : {i,e,d,c,b,a} = 6'h13;
|
||||
7'h27 : {i,e,d,c,b,a} = 6'h33;
|
||||
7'h28 : {i,e,d,c,b,a} = 6'h34;
|
||||
7'h29 : {i,e,d,c,b,a} = 6'h34;
|
||||
7'h2a : {i,e,d,c,b,a} = 6'h15;
|
||||
7'h2b : {i,e,d,c,b,a} = 6'h35;
|
||||
7'h2c : {i,e,d,c,b,a} = 6'h16;
|
||||
7'h2d : {i,e,d,c,b,a} = 6'h36;
|
||||
7'h2e : {i,e,d,c,b,a} = 6'h17;
|
||||
7'h2f : {i,e,d,c,b,a} = 6'h17;
|
||||
7'h30 : {i,e,d,c,b,a} = 6'h33;
|
||||
7'h31 : {i,e,d,c,b,a} = 6'h33;
|
||||
7'h32 : {i,e,d,c,b,a} = 6'h19;
|
||||
7'h33 : {i,e,d,c,b,a} = 6'h39;
|
||||
7'h34 : {i,e,d,c,b,a} = 6'h1a;
|
||||
7'h35 : {i,e,d,c,b,a} = 6'h3a;
|
||||
7'h36 : {i,e,d,c,b,a} = 6'h1b;
|
||||
7'h37 : {i,e,d,c,b,a} = 6'h1b;
|
||||
7'h38 : {i,e,d,c,b,a} = 6'h1c;
|
||||
7'h39 : {i,e,d,c,b,a} = 6'h3c;
|
||||
7'h3a : {i,e,d,c,b,a} = 6'h1d;
|
||||
7'h3b : {i,e,d,c,b,a} = 6'h1d;
|
||||
7'h3c : {i,e,d,c,b,a} = 6'h1e;
|
||||
7'h3d : {i,e,d,c,b,a} = 6'h1e;
|
||||
7'h3e : {i,e,d,c,b,a} = 6'h35;
|
||||
7'h3f : {i,e,d,c,b,a} = 6'h35;
|
||||
7'h40 : {i,e,d,c,b,a} = 6'h06;
|
||||
7'h41 : {i,e,d,c,b,a} = 6'h39;
|
||||
7'h42 : {i,e,d,c,b,a} = 6'h11;
|
||||
7'h43 : {i,e,d,c,b,a} = 6'h2e;
|
||||
7'h44 : {i,e,d,c,b,a} = 6'h12;
|
||||
7'h45 : {i,e,d,c,b,a} = 6'h2d;
|
||||
7'h46 : {i,e,d,c,b,a} = 6'h23;
|
||||
7'h47 : {i,e,d,c,b,a} = 6'h1c;
|
||||
7'h48 : {i,e,d,c,b,a} = 6'h14;
|
||||
7'h49 : {i,e,d,c,b,a} = 6'h2b;
|
||||
7'h4a : {i,e,d,c,b,a} = 6'h25;
|
||||
7'h4b : {i,e,d,c,b,a} = 6'h1a;
|
||||
7'h4c : {i,e,d,c,b,a} = 6'h26;
|
||||
7'h4d : {i,e,d,c,b,a} = 6'h19;
|
||||
7'h4e : {i,e,d,c,b,a} = 6'h38;
|
||||
7'h4f : {i,e,d,c,b,a} = 6'h38;
|
||||
7'h50 : {i,e,d,c,b,a} = 6'h18;
|
||||
7'h51 : {i,e,d,c,b,a} = 6'h27;
|
||||
7'h52 : {i,e,d,c,b,a} = 6'h29;
|
||||
7'h53 : {i,e,d,c,b,a} = 6'h16;
|
||||
7'h54 : {i,e,d,c,b,a} = 6'h2a;
|
||||
7'h55 : {i,e,d,c,b,a} = 6'h15;
|
||||
7'h56 : {i,e,d,c,b,a} = 6'h0b;
|
||||
7'h57 : {i,e,d,c,b,a} = 6'h34;
|
||||
7'h58 : {i,e,d,c,b,a} = 6'h2c;
|
||||
7'h59 : {i,e,d,c,b,a} = 6'h13;
|
||||
7'h5a : {i,e,d,c,b,a} = 6'h0d;
|
||||
7'h5b : {i,e,d,c,b,a} = 6'h32;
|
||||
7'h5c : {i,e,d,c,b,a} = 6'h0e;
|
||||
7'h5d : {i,e,d,c,b,a} = 6'h31;
|
||||
7'h5e : {i,e,d,c,b,a} = 6'h05;
|
||||
7'h5f : {i,e,d,c,b,a} = 6'h3a;
|
||||
7'h60 : {i,e,d,c,b,a} = 6'h09;
|
||||
7'h61 : {i,e,d,c,b,a} = 6'h09;
|
||||
7'h62 : {i,e,d,c,b,a} = 6'h31;
|
||||
7'h63 : {i,e,d,c,b,a} = 6'h0e;
|
||||
7'h64 : {i,e,d,c,b,a} = 6'h32;
|
||||
7'h65 : {i,e,d,c,b,a} = 6'h0d;
|
||||
7'h66 : {i,e,d,c,b,a} = 6'h13;
|
||||
7'h67 : {i,e,d,c,b,a} = 6'h0c;
|
||||
7'h68 : {i,e,d,c,b,a} = 6'h34;
|
||||
7'h69 : {i,e,d,c,b,a} = 6'h0b;
|
||||
7'h6a : {i,e,d,c,b,a} = 6'h15;
|
||||
7'h6b : {i,e,d,c,b,a} = 6'h0a;
|
||||
7'h6c : {i,e,d,c,b,a} = 6'h16;
|
||||
7'h6d : {i,e,d,c,b,a} = 6'h09;
|
||||
7'h6e : {i,e,d,c,b,a} = 6'h28;
|
||||
7'h6f : {i,e,d,c,b,a} = 6'h28;
|
||||
7'h70 : {i,e,d,c,b,a} = 6'h0c;
|
||||
7'h71 : {i,e,d,c,b,a} = 6'h33;
|
||||
7'h72 : {i,e,d,c,b,a} = 6'h19;
|
||||
7'h73 : {i,e,d,c,b,a} = 6'h06;
|
||||
7'h74 : {i,e,d,c,b,a} = 6'h1a;
|
||||
7'h75 : {i,e,d,c,b,a} = 6'h05;
|
||||
7'h76 : {i,e,d,c,b,a} = 6'h24;
|
||||
7'h77 : {i,e,d,c,b,a} = 6'h24;
|
||||
7'h78 : {i,e,d,c,b,a} = 6'h1c;
|
||||
7'h79 : {i,e,d,c,b,a} = 6'h03;
|
||||
7'h7a : {i,e,d,c,b,a} = 6'h22;
|
||||
7'h7b : {i,e,d,c,b,a} = 6'h22;
|
||||
7'h7c : {i,e,d,c,b,a} = 6'h21;
|
||||
7'h7d : {i,e,d,c,b,a} = 6'h21;
|
||||
7'h7e : {i,e,d,c,b,a} = 6'h0a;
|
||||
7'h7f : {i,e,d,c,b,a} = 6'h0a;
|
||||
endcase
|
||||
|
||||
case (ein_dat[4:0])
|
||||
5'h00 : rd1_part = 1'b1;
|
||||
5'h01 : rd1_part = 1'b1;
|
||||
5'h02 : rd1_part = 1'b1;
|
||||
5'h03 : rd1_part = 1'b0;
|
||||
5'h04 : rd1_part = 1'b1;
|
||||
5'h05 : rd1_part = 1'b0;
|
||||
5'h06 : rd1_part = 1'b0;
|
||||
5'h07 : rd1_part = 1'b0;
|
||||
5'h08 : rd1_part = 1'b1;
|
||||
5'h09 : rd1_part = 1'b0;
|
||||
5'h0a : rd1_part = 1'b0;
|
||||
5'h0b : rd1_part = 1'b0;
|
||||
5'h0c : rd1_part = 1'b0;
|
||||
5'h0d : rd1_part = 1'b0;
|
||||
5'h0e : rd1_part = 1'b0;
|
||||
5'h0f : rd1_part = 1'b1;
|
||||
5'h10 : rd1_part = 1'b1;
|
||||
5'h11 : rd1_part = 1'b0;
|
||||
5'h12 : rd1_part = 1'b0;
|
||||
5'h13 : rd1_part = 1'b0;
|
||||
5'h14 : rd1_part = 1'b0;
|
||||
5'h15 : rd1_part = 1'b0;
|
||||
5'h16 : rd1_part = 1'b0;
|
||||
5'h17 : rd1_part = 1'b1;
|
||||
5'h18 : rd1_part = 1'b1;
|
||||
5'h19 : rd1_part = 1'b0;
|
||||
5'h1a : rd1_part = 1'b0;
|
||||
5'h1b : rd1_part = 1'b1;
|
||||
5'h1c : rd1_part = 1'b0;
|
||||
5'h1d : rd1_part = 1'b1;
|
||||
5'h1e : rd1_part = 1'b1;
|
||||
5'h1f : rd1_part = 1'b1;
|
||||
endcase
|
||||
end
|
||||
|
||||
wire disp4 = (!F & !G);
|
||||
wire disp5 = (F & G);
|
||||
wire disp6 = ((F ^ G) & K);
|
||||
wire invert_fj = !(((rd1_part | K) ^ ein_rd) ? disp5 : (disp4 | disp6));
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
g = (!(!F & !H) & !G) ^ invert_fj;
|
||||
h = (!H) ^ invert_fj;
|
||||
end
|
||||
|
||||
wire f0,f1,f2,f3,f4;
|
||||
|
||||
stratixii_lcell_comb f0_I (
|
||||
.dataa(!ein_dat[3]),
|
||||
.datab(!ein_dat[4]),
|
||||
.datac(!ein_dat[1]),
|
||||
.datad(!ein_dat[2]),
|
||||
.datae(!ein_dat[0]),
|
||||
.dataf(1'b1),.datag(1'b1),
|
||||
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
|
||||
.combout(f0 ));
|
||||
defparam f0_I .shared_arith = "off";
|
||||
defparam f0_I .extended_lut = "off";
|
||||
defparam f0_I .lut_mask = 64'h0224244002242440;
|
||||
|
||||
stratixii_lcell_comb f1_I (
|
||||
.dataa(!ein_rd),
|
||||
.datab(!ein_dat[7]),
|
||||
.datac(!ein_dat[6]),
|
||||
.datad(!ein_dat[5]),
|
||||
.datae(!kin_ena),
|
||||
.dataf(1'b1),.datag(1'b1),
|
||||
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
|
||||
.combout(f1 ));
|
||||
defparam f1_I .shared_arith = "off";
|
||||
defparam f1_I .extended_lut = "off";
|
||||
defparam f1_I .lut_mask = 64'h0F03AA590F03AA59;
|
||||
|
||||
stratixii_lcell_comb f2_I (
|
||||
.dataa(!ein_rd),
|
||||
.datab(!ein_dat[7]),
|
||||
.datac(!ein_dat[6]),
|
||||
.datad(!ein_dat[5]),
|
||||
.datae(!kin_ena),
|
||||
.dataf(1'b1),.datag(1'b1),
|
||||
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
|
||||
.combout(f2 ));
|
||||
defparam f2_I .shared_arith = "off";
|
||||
defparam f2_I .extended_lut = "off";
|
||||
defparam f2_I .lut_mask = 64'h00F355A600F355A6;
|
||||
|
||||
stratixii_lcell_comb f3_I (
|
||||
.dataa(!f4 ),
|
||||
.datab(!f0 ),
|
||||
.datac(!ein_rd),
|
||||
.datad(!f1 ),
|
||||
.datae(!f2 ),
|
||||
.dataf(1'b1),.datag(1'b1),
|
||||
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
|
||||
.combout(f3 ));
|
||||
defparam f3_I .shared_arith = "off";
|
||||
defparam f3_I .extended_lut = "off";
|
||||
defparam f3_I .lut_mask = 64'h7800FF597800FF59;
|
||||
|
||||
stratixii_lcell_comb f4_I (
|
||||
.dataa(!ein_dat[3]),
|
||||
.datab(!ein_dat[4]),
|
||||
.datac(!ein_dat[1]),
|
||||
.datad(!ein_dat[2]),
|
||||
.datae(!ein_dat[0]),
|
||||
.dataf(1'b1),.datag(1'b1),
|
||||
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
|
||||
.combout(f4 ));
|
||||
defparam f4_I .shared_arith = "off";
|
||||
defparam f4_I .extended_lut = "off";
|
||||
defparam f4_I .lut_mask = 64'h055E5EE8055E5EE8;
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
f = f3;
|
||||
end
|
||||
|
||||
wire j0,j1,j2,j3,j4,j5;
|
||||
|
||||
stratixii_lcell_comb j0_I (
|
||||
.dataa(!ein_dat[1]),
|
||||
.datab(!ein_dat[3]),
|
||||
.datac(!ein_dat[4]),
|
||||
.datad(!ein_dat[2]),
|
||||
.datae(!ein_dat[0]),
|
||||
.dataf(1'b1),.datag(1'b1),
|
||||
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
|
||||
.combout(j0 ));
|
||||
defparam j0_I .shared_arith = "off";
|
||||
defparam j0_I .extended_lut = "off";
|
||||
defparam j0_I .lut_mask = 64'h117676E8117676E8;
|
||||
|
||||
stratixii_lcell_comb j1_I (
|
||||
.dataa(!ein_dat[1]),
|
||||
.datab(!ein_dat[3]),
|
||||
.datac(!ein_dat[4]),
|
||||
.datad(!ein_dat[2]),
|
||||
.datae(!ein_dat[0]),
|
||||
.dataf(1'b1),.datag(1'b1),
|
||||
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
|
||||
.combout(j1 ));
|
||||
defparam j1_I .shared_arith = "off";
|
||||
defparam j1_I .extended_lut = "off";
|
||||
defparam j1_I .lut_mask = 64'h0418182004181820;
|
||||
|
||||
stratixii_lcell_comb j2_I (
|
||||
.dataa(!ein_rd),
|
||||
.datab(!ein_dat[7]),
|
||||
.datac(!ein_dat[5]),
|
||||
.datad(!ein_dat[6]),
|
||||
.datae(!kin_ena),
|
||||
.dataf(1'b1),.datag(1'b1),
|
||||
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
|
||||
.combout(j2 ));
|
||||
defparam j2_I .shared_arith = "off";
|
||||
defparam j2_I .extended_lut = "off";
|
||||
defparam j2_I .lut_mask = 64'h5339A6665339A666;
|
||||
|
||||
stratixii_lcell_comb j3_I (
|
||||
.datac(!ein_dat[5]),
|
||||
.datad(!ein_dat[6]),
|
||||
.datae(!kin_ena),
|
||||
.dataa(1'b1),.datab(1'b1),.dataf(1'b1),.datag(1'b1),
|
||||
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
|
||||
.combout(j3 ));
|
||||
defparam j3_I .shared_arith = "off";
|
||||
defparam j3_I .extended_lut = "off";
|
||||
defparam j3_I .lut_mask = 64'hF00F0000F00F0000;
|
||||
|
||||
stratixii_lcell_comb j4_I (
|
||||
.datab(!ein_dat[7]),
|
||||
.datac(!ein_dat[5]),
|
||||
.datad(!ein_dat[6]),
|
||||
.datae(!kin_ena),
|
||||
.dataa(1'b1),.dataf(1'b1),.datag(1'b1),
|
||||
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
|
||||
.combout(j4 ));
|
||||
defparam j4_I .shared_arith = "off";
|
||||
defparam j4_I .extended_lut = "off";
|
||||
defparam j4_I .lut_mask = 64'h0003000000030000;
|
||||
|
||||
stratixii_lcell_comb j5_I (
|
||||
.dataa(!j0 ),
|
||||
.datab(!j1 ),
|
||||
.datac(!j2 ),
|
||||
.datad(!j3 ),
|
||||
.datae(!j4 ),
|
||||
.dataf(1'b1),.datag(1'b1),
|
||||
.cin(1'b1),.sharein(1'b0),.sumout(),.cout(),.shareout(),
|
||||
.combout(j5 ));
|
||||
defparam j5_I .shared_arith = "off";
|
||||
defparam j5_I .extended_lut = "off";
|
||||
defparam j5_I .lut_mask = 64'hF07870A6F07870A6;
|
||||
|
||||
always @(*)
|
||||
begin
|
||||
j = j5;
|
||||
end
|
||||
end
|
||||
|
||||
endgenerate
|
||||
|
||||
always @(posedge clk or posedge rst)
|
||||
begin
|
||||
if (rst)
|
||||
begin
|
||||
eout_rdreg <= 0;
|
||||
eout_val <= 0;
|
||||
eout_dat <= 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
eout_val <= 0;
|
||||
if (ein_ena | kin_ena)
|
||||
begin
|
||||
eout_rdreg <= eout_rdcomb;
|
||||
eout_val <= ein_ena | kin_ena;
|
||||
eout_dat <= {j,h,g,f,i,e,d,c,b,a};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
243
Advanced Synthesis Cookbook/communication/encoder_tb.v
Normal file
243
Advanced Synthesis Cookbook/communication/encoder_tb.v
Normal file
@ -0,0 +1,243 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 04-07-2006
|
||||
// compare 8b10b encoder / decoders
|
||||
|
||||
module encoder_tb ();
|
||||
|
||||
reg fail ;
|
||||
|
||||
reg clk;
|
||||
reg rst_n;
|
||||
reg kin_ena;
|
||||
reg ein_ena;
|
||||
reg [7:0] ein_dat;
|
||||
reg ein_rd;
|
||||
|
||||
wire eout_val_a,eout_val_b;
|
||||
wire [9:0] eout_dat_a,eout_dat_b;
|
||||
wire eout_rdcomb_a,eout_rdcomb_b;
|
||||
wire eout_rdreg_a,eout_rdreg_b;
|
||||
|
||||
wire valid,kerr;
|
||||
|
||||
///////////////////////////////////
|
||||
// Encoder units
|
||||
///////////////////////////////////
|
||||
encoder_8b10b ea (
|
||||
.clk(clk),
|
||||
.rst(!rst_n),
|
||||
.kin_ena(kin_ena),
|
||||
.ein_ena(ein_ena),
|
||||
.ein_dat(ein_dat),
|
||||
.ein_rd(ein_rd),
|
||||
.eout_val(eout_val_a),
|
||||
.eout_dat(eout_dat_a),
|
||||
.eout_rdcomb(eout_rdcomb_a),
|
||||
.eout_rdreg(eout_rdreg_a)
|
||||
);
|
||||
defparam ea .METHOD = 0;
|
||||
|
||||
encoder_8b10b eb (
|
||||
.clk(clk),
|
||||
.rst(!rst_n),
|
||||
.kin_ena(kin_ena),
|
||||
.ein_ena(ein_ena),
|
||||
.ein_dat(ein_dat),
|
||||
.ein_rd(ein_rd),
|
||||
.eout_val(eout_val_b),
|
||||
.eout_dat(eout_dat_b),
|
||||
.eout_rdcomb(eout_rdcomb_b),
|
||||
.eout_rdreg(eout_rdreg_b)
|
||||
);
|
||||
defparam eb .METHOD = 1;
|
||||
|
||||
/////////////////////////////////////////
|
||||
//Lag some signals for decoder checking
|
||||
/////////////////////////////////////////
|
||||
reg [7:0] late_data;
|
||||
reg [7:0] late_late_data;
|
||||
reg late_ein_rd;
|
||||
|
||||
always @(posedge clk) begin
|
||||
late_late_data <= late_data;
|
||||
late_data <= ein_dat;
|
||||
late_ein_rd <= ein_rd;
|
||||
end
|
||||
|
||||
///////////////////////////////////
|
||||
// Decoder units
|
||||
///////////////////////////////////
|
||||
|
||||
wire [7:0] dat_de,dat_df;
|
||||
wire kerr_de,kerr_df;
|
||||
wire rderr_de,rderr_df;
|
||||
wire k_de,k_df;
|
||||
wire rdreg_de,rdreg_df;
|
||||
|
||||
// fake some errors
|
||||
reg inject_rd_error;
|
||||
reg [63:0] inject_k_error;
|
||||
|
||||
decoder_8b10b de (
|
||||
.clk(clk),
|
||||
.rst(!rst_n),
|
||||
.din_ena(1'b1),
|
||||
.din_dat(eout_dat_a ^ inject_k_error[9:0]),
|
||||
.din_rd(late_ein_rd ^ inject_rd_error),
|
||||
.dout_val(),
|
||||
.dout_dat(dat_de),
|
||||
.dout_k(k_de),
|
||||
.dout_kerr(kerr_de),
|
||||
.dout_rderr(rderr_de),
|
||||
.dout_rdcomb(),
|
||||
.dout_rdreg(rdreg_de)
|
||||
);
|
||||
defparam de .METHOD = 0;
|
||||
|
||||
decoder_8b10b df (
|
||||
.clk(clk),
|
||||
.rst(!rst_n),
|
||||
.din_ena(1'b1),
|
||||
.din_dat(eout_dat_a ^ inject_k_error[9:0]),
|
||||
.din_rd(late_ein_rd ^ inject_rd_error),
|
||||
.dout_val(),
|
||||
.dout_dat(dat_df),
|
||||
.dout_k(k_df),
|
||||
.dout_kerr(kerr_df),
|
||||
.dout_rderr(rderr_df),
|
||||
.dout_rdcomb(),
|
||||
.dout_rdreg(rdreg_df)
|
||||
);
|
||||
defparam df .METHOD = 1;
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
rst_n = 1;
|
||||
kin_ena = 0;
|
||||
ein_ena = 0;
|
||||
ein_dat = 0;
|
||||
ein_rd = 0;
|
||||
fail = 0;
|
||||
inject_rd_error = 0;
|
||||
inject_k_error = 1;
|
||||
|
||||
#10 rst_n = 0;
|
||||
#10 rst_n = 1;
|
||||
#2000000
|
||||
if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
always begin
|
||||
#100 clk = ~clk;
|
||||
end
|
||||
|
||||
///////////////////////////////////////////
|
||||
// not all data for transmit is legal.
|
||||
///////////////////////////////////////////
|
||||
reg [3:0] tmp;
|
||||
always @(negedge clk or negedge rst_n) begin
|
||||
ein_ena = $random;
|
||||
kin_ena = !ein_ena;
|
||||
tmp = $random % 4'hd;
|
||||
|
||||
if (kin_ena) begin
|
||||
case (tmp)
|
||||
// valid K signals
|
||||
4'h0 : ein_dat = 8'b000_11100;
|
||||
4'h1 : ein_dat = 8'b000_11100;
|
||||
4'h2 : ein_dat = 8'b001_11100;
|
||||
4'h3 : ein_dat = 8'b010_11100;
|
||||
4'h4 : ein_dat = 8'b011_11100;
|
||||
4'h5 : ein_dat = 8'b100_11100;
|
||||
4'h6 : ein_dat = 8'b101_11100;
|
||||
4'h7 : ein_dat = 8'b110_11100;
|
||||
4'h8 : ein_dat = 8'b111_11100;
|
||||
4'h9 : ein_dat = 8'b111_10111;
|
||||
4'ha : ein_dat = 8'b111_11011;
|
||||
4'hb : ein_dat = 8'b111_11101;
|
||||
4'hc : ein_dat = 8'b111_11110;
|
||||
// 4'hd : ein_dat = 8'b111_11111;
|
||||
default : ein_dat = 0;
|
||||
endcase
|
||||
end
|
||||
else
|
||||
ein_dat = $random;
|
||||
end
|
||||
|
||||
// random inputs
|
||||
always @(negedge clk) begin
|
||||
|
||||
// TX rd is completely random
|
||||
ein_rd = $random;
|
||||
|
||||
// tell the RX the wrong RD sometimes, data
|
||||
// should be OK
|
||||
inject_rd_error = $random;
|
||||
|
||||
inject_k_error = (inject_k_error << 1) | inject_k_error[63];
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
#10
|
||||
|
||||
///////////////////////////////////
|
||||
// compare encoders A and B
|
||||
///////////////////////////////////
|
||||
if (eout_val_a != eout_val_b ||
|
||||
eout_dat_a != eout_dat_b ||
|
||||
eout_rdcomb_a != eout_rdcomb_b ||
|
||||
eout_rdreg_a != eout_rdreg_b
|
||||
)
|
||||
begin
|
||||
$display ("Mismatch between A and B at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
|
||||
///////////////////////////////////
|
||||
// compare decoder E to encoded data
|
||||
///////////////////////////////////
|
||||
if (dat_de != late_late_data) begin
|
||||
// make sure it isn't an error that was injected intentionally
|
||||
if (~|inject_k_error[10:0]) begin
|
||||
$display ("Decoded data mismatch at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
end
|
||||
|
||||
///////////////////////////////////
|
||||
// compare decoders E and F
|
||||
///////////////////////////////////
|
||||
if (dat_de != dat_df ||
|
||||
kerr_de != kerr_df ||
|
||||
rderr_de != rderr_df ||
|
||||
k_de != k_df ||
|
||||
rdreg_de != rdreg_df)
|
||||
begin
|
||||
$display ("Mismatch between E and F at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
271
Advanced Synthesis Cookbook/communication/gear_expt.cpp
Normal file
271
Advanced Synthesis Cookbook/communication/gear_expt.cpp
Normal file
@ -0,0 +1,271 @@
|
||||
// Copyright 2009 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 03-27-2009
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void panic (char * msg)
|
||||
{
|
||||
fprintf (stdout,"PANIC: %s\n",msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int const word_out_bits = 67;
|
||||
int const word_in_bits = 40;
|
||||
int const storage_len = word_out_bits-1+word_in_bits;
|
||||
bool storage [storage_len];
|
||||
int holding = 0;
|
||||
|
||||
void init_storage ()
|
||||
{
|
||||
int n = 0;
|
||||
for (n=0; n<storage_len; n++)
|
||||
{
|
||||
storage[n] = false;
|
||||
}
|
||||
for (n=storage_len-1; n>=storage_len-word_out_bits; n--)
|
||||
{
|
||||
storage[n] = true;
|
||||
}
|
||||
holding = word_out_bits;
|
||||
}
|
||||
|
||||
// bool OK?
|
||||
bool shl_storage (int shift_dist)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
for (n=storage_len-1; n>=storage_len-shift_dist; n--)
|
||||
{
|
||||
if (storage[n])
|
||||
{
|
||||
//panic ("SHL is losing most significant bits");
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
for (n=storage_len-1; n>=shift_dist; n--)
|
||||
{
|
||||
storage[n] = storage[n-shift_dist];
|
||||
}
|
||||
for (n=0; n<shift_dist; n++)
|
||||
{
|
||||
storage[n] = false;
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
|
||||
// bool OK?
|
||||
bool extract_word (int ms_idx)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
// these bits are TAKEN
|
||||
for (n=0; n<word_out_bits; n++)
|
||||
{
|
||||
if (!storage[ms_idx-n])
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
|
||||
for (n=0; n<word_out_bits; n++)
|
||||
{
|
||||
storage[ms_idx-n] = false;
|
||||
}
|
||||
|
||||
holding -= word_out_bits;
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool insert_data (int shift_dist)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
if (shift_dist < 0)
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
if (holding > 0 && !storage[word_in_bits+shift_dist])
|
||||
{
|
||||
// not adjoining exitsting residue
|
||||
return (false);
|
||||
}
|
||||
for (n=0; n<word_in_bits; n++)
|
||||
{
|
||||
if ((n+shift_dist) >= storage_len)
|
||||
{
|
||||
// ("Access out of range");
|
||||
return (false);
|
||||
}
|
||||
if (storage[n+shift_dist])
|
||||
{
|
||||
// ("New data is stomping old");
|
||||
return (false);
|
||||
}
|
||||
storage[n+shift_dist] = true;
|
||||
}
|
||||
holding += word_in_bits;
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
// scratch area for solution
|
||||
int dat_shift [100];
|
||||
int store_shift [100];
|
||||
int extract_point [100];
|
||||
|
||||
// bool found a solution?
|
||||
bool search (int phase)
|
||||
{
|
||||
bool viable = true;
|
||||
bool last_storage [storage_len];
|
||||
int last_holding;
|
||||
int n,a,b,c,bb,aa;
|
||||
|
||||
if (phase == word_out_bits+1) return (true);
|
||||
|
||||
// save state
|
||||
for (n=0; n<storage_len; n++)
|
||||
{
|
||||
last_storage[n] = storage[n];
|
||||
}
|
||||
last_holding = holding;
|
||||
|
||||
//fprintf (stdout,"phase %d - holding %d\n",phase,holding);
|
||||
for (aa = 0; aa < 3; aa++)
|
||||
{
|
||||
if (aa == 0) a = 105;
|
||||
else if (aa == 1) a = 92;
|
||||
else if (aa == 2) a = 78;
|
||||
|
||||
for (bb = 0; bb < 4; bb++)
|
||||
{
|
||||
if (bb == 0) b = 47;
|
||||
else if (bb == 1) b = 40;
|
||||
else if (bb == 2) b = 34;
|
||||
else if (bb == 3) b = 33;
|
||||
|
||||
for (c=0;c<14;c++) // 13 is ok, not sure about less
|
||||
{
|
||||
// execute phase - see if it works
|
||||
viable = true;
|
||||
|
||||
if (holding >= word_out_bits)
|
||||
{
|
||||
if (!extract_word (a))
|
||||
{
|
||||
viable = false;
|
||||
bb = 100; // if A doesn't work all B,C are wash
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// extract point a is a don't care
|
||||
a = 0;
|
||||
}
|
||||
|
||||
if (viable)
|
||||
{
|
||||
if (!shl_storage (b))
|
||||
{
|
||||
viable = false;
|
||||
c = 100; // if B doesn't work all C are wash
|
||||
}
|
||||
}
|
||||
if (viable)
|
||||
{
|
||||
if (!insert_data (c)) viable = false;
|
||||
}
|
||||
|
||||
// if it looks OK keep searching
|
||||
if (viable)
|
||||
{
|
||||
fprintf (stdout,"phase %d - %d %d %d works\n",phase,a,b,c);
|
||||
if (search (phase+1))
|
||||
{
|
||||
fprintf (stdout,"sol phase %d ext %d shl storage %d shl data %d\n",
|
||||
phase,a,b,c);
|
||||
|
||||
dat_shift [phase] = c;
|
||||
store_shift [phase] = b;
|
||||
extract_point [phase] = a;
|
||||
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
|
||||
// restore state
|
||||
for (n=0; n<storage_len; n++)
|
||||
{
|
||||
storage[n] = last_storage[n];
|
||||
}
|
||||
holding = last_holding;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
int n = 0;
|
||||
init_storage ();
|
||||
if (search (0))
|
||||
{
|
||||
// phase 0 has 67 bits, doesn't really matter
|
||||
// where, let phase 67 decide where phase 0 extracts
|
||||
extract_point[0] = extract_point[67];
|
||||
|
||||
// Changes for hardware :
|
||||
// The search will be doing the extract and shifts
|
||||
// simultaneously.
|
||||
// In hardware data shift is 1 tick earlier
|
||||
|
||||
for (n=0; n<word_out_bits; n++)
|
||||
{
|
||||
fprintf (stdout," 6'h%02x : begin ",n);
|
||||
fprintf (stdout," ds <= 4'h%x;",dat_shift[(n+1)%67]);
|
||||
|
||||
fprintf (stdout," ss <= 2'h%x; ",
|
||||
store_shift[n] == 33 ? 0 :
|
||||
store_shift[n] == 34 ? 1 :
|
||||
store_shift[n] == 40 ? 2 :
|
||||
store_shift[n] == 47 ? 3 : 0xf);
|
||||
|
||||
fprintf (stdout," ep <= 2'h%x; ",
|
||||
extract_point[n] == 0 ? 0 :
|
||||
extract_point[n] == 78 ? 1 :
|
||||
extract_point[n] == 92 ? 2 :
|
||||
extract_point[n] == 105 ? 3 : 0xf);
|
||||
|
||||
fprintf (stdout," end\n");
|
||||
if (n == 0x3f) fprintf (stdout,"\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
315
Advanced Synthesis Cookbook/communication/gear_expt2.cpp
Normal file
315
Advanced Synthesis Cookbook/communication/gear_expt2.cpp
Normal file
@ -0,0 +1,315 @@
|
||||
// Copyright 2009 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 03-27-2009
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
|
||||
void panic (char * msg)
|
||||
{
|
||||
fprintf (stdout,"PANIC: %s\n",msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int const word_out_bits = 40;
|
||||
int const word_in_bits = 67;
|
||||
int const storage_len = word_out_bits-1+word_in_bits;
|
||||
bool storage [storage_len];
|
||||
int holding = 0;
|
||||
|
||||
void init_storage ()
|
||||
{
|
||||
int n = 0;
|
||||
for (n=0; n<storage_len; n++)
|
||||
{
|
||||
storage[n] = false;
|
||||
}
|
||||
for (n=storage_len-1; n>=storage_len-word_out_bits; n--)
|
||||
{
|
||||
storage[n] = true;
|
||||
}
|
||||
holding = word_out_bits;
|
||||
}
|
||||
|
||||
// bool OK?
|
||||
bool shl_storage (int shift_dist)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
for (n=storage_len-1; n>=storage_len-shift_dist; n--)
|
||||
{
|
||||
if (storage[n])
|
||||
{
|
||||
//panic ("SHL is losing most significant bits");
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
for (n=storage_len-1; n>=shift_dist; n--)
|
||||
{
|
||||
storage[n] = storage[n-shift_dist];
|
||||
}
|
||||
for (n=0; n<shift_dist; n++)
|
||||
{
|
||||
storage[n] = false;
|
||||
}
|
||||
return (true);
|
||||
}
|
||||
|
||||
// bool OK?
|
||||
bool extract_word (int ms_idx)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
// these bits are TAKEN
|
||||
for (n=0; n<word_out_bits; n++)
|
||||
{
|
||||
if (!storage[ms_idx-n])
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
}
|
||||
|
||||
for (n=0; n<word_out_bits; n++)
|
||||
{
|
||||
storage[ms_idx-n] = false;
|
||||
}
|
||||
|
||||
holding -= word_out_bits;
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool insert_data (int shift_dist)
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
if (shift_dist < 0)
|
||||
{
|
||||
return (false);
|
||||
}
|
||||
if (holding > 0 && !storage[word_in_bits+shift_dist])
|
||||
{
|
||||
// not adjoining exitsting residue
|
||||
return (false);
|
||||
}
|
||||
for (n=0; n<word_in_bits; n++)
|
||||
{
|
||||
if ((n+shift_dist) >= storage_len)
|
||||
{
|
||||
// ("Access out of range");
|
||||
return (false);
|
||||
}
|
||||
if (storage[n+shift_dist])
|
||||
{
|
||||
// ("New data is stomping old");
|
||||
return (false);
|
||||
}
|
||||
storage[n+shift_dist] = true;
|
||||
}
|
||||
holding += word_in_bits;
|
||||
|
||||
return (true);
|
||||
}
|
||||
|
||||
// scratch area for solution
|
||||
int dat_shift [100];
|
||||
int store_shift [100];
|
||||
int extract_point [100];
|
||||
|
||||
// bool found a solution?
|
||||
bool search (int phase)
|
||||
{
|
||||
bool viable = true;
|
||||
bool last_storage [storage_len];
|
||||
int last_holding;
|
||||
int n,a,b,c,bb,aa;
|
||||
|
||||
if (phase == 68) return (true);
|
||||
|
||||
// save state
|
||||
for (n=0; n<storage_len; n++)
|
||||
{
|
||||
last_storage[n] = storage[n];
|
||||
}
|
||||
last_holding = holding;
|
||||
|
||||
//fprintf (stdout,"phase %d - holding %d\n",phase,holding);
|
||||
for (aa = 0; aa < 3; aa++)
|
||||
{
|
||||
if (aa == 0) a = 105;
|
||||
else if (aa == 1) a = 95;
|
||||
else if (aa == 2) a = 100;
|
||||
|
||||
for (bb = 0; bb < 2; bb++)
|
||||
{
|
||||
if (bb == 0) b = 40;
|
||||
else if (bb == 1) b = 45;
|
||||
|
||||
for (c=0;c<32;c++) // 13 is ok, not sure about less
|
||||
{
|
||||
// execute phase - see if it works
|
||||
viable = true;
|
||||
|
||||
if (holding >= word_out_bits)
|
||||
{
|
||||
if (!extract_word (a))
|
||||
{
|
||||
viable = false;
|
||||
bb = 100; // if A doesn't work all B,C are wash
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// extract point a is a don't care
|
||||
a = 0;
|
||||
}
|
||||
|
||||
if (viable)
|
||||
{
|
||||
if (!shl_storage (b))
|
||||
{
|
||||
viable = false;
|
||||
c = 100; // if B doesn't work all C are wash
|
||||
}
|
||||
}
|
||||
if (viable)
|
||||
{
|
||||
if (holding >= word_out_bits)
|
||||
{
|
||||
// skip the insert this round
|
||||
c = 100;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!insert_data (c)) viable = false;
|
||||
}
|
||||
}
|
||||
|
||||
// if it looks OK keep searching
|
||||
if (viable)
|
||||
{
|
||||
//fprintf (stdout,"phase %d - %d %d %d works\n",phase,a,b,c);
|
||||
if (search (phase+1))
|
||||
{
|
||||
fprintf (stdout,"sol phase %d holding %d ext %d shl storage %d shl data %d\n",
|
||||
phase,last_holding,a,b,c);
|
||||
|
||||
dat_shift [phase] = (c == 100) ? -1 : c;
|
||||
store_shift [phase] = b;
|
||||
extract_point [phase] = a;
|
||||
|
||||
return (true);
|
||||
}
|
||||
}
|
||||
|
||||
// restore state
|
||||
for (n=0; n<storage_len; n++)
|
||||
{
|
||||
storage[n] = last_storage[n];
|
||||
}
|
||||
holding = last_holding;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (false);
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
int n = 0;
|
||||
int shift_used[100];
|
||||
|
||||
init_storage ();
|
||||
if (search (0))
|
||||
{
|
||||
// phase 0 has 67 bits, doesn't really matter
|
||||
// where, let phase 67 decide where phase 0 extracts
|
||||
extract_point[0] = extract_point[67];
|
||||
|
||||
// Changes for hardware :
|
||||
// The search will be doing the extract and shifts
|
||||
// simultaneously.
|
||||
// In hardware data shift is 1 tick earlier
|
||||
|
||||
for (n=0; n<67; n++)
|
||||
{
|
||||
fprintf (stdout," 6'h%02x : begin ",n);
|
||||
fprintf (stdout," ds <= 4'h%x;",
|
||||
dat_shift[(n+1)%67] == 0 ? 0 :
|
||||
dat_shift[(n+1)%67] == 1 ? 1 :
|
||||
dat_shift[(n+1)%67] == 2 ? 2 :
|
||||
dat_shift[(n+1)%67] == 3 ? 3 :
|
||||
dat_shift[(n+1)%67] == 4 ? 4 :
|
||||
dat_shift[(n+1)%67] == 13 ? 5 :
|
||||
dat_shift[(n+1)%67] == 14 ? 6 :
|
||||
dat_shift[(n+1)%67] == 15 ? 7 :
|
||||
dat_shift[(n+1)%67] == 16 ? 8 :
|
||||
dat_shift[(n+1)%67] == 17 ? 9 :
|
||||
dat_shift[(n+1)%67] == 26 ? 10 :
|
||||
dat_shift[(n+1)%67] == 27 ? 11 :
|
||||
dat_shift[(n+1)%67] == 28 ? 12 :
|
||||
dat_shift[(n+1)%67] == 29 ? 13 :
|
||||
dat_shift[(n+1)%67] == 30 ? 14 :
|
||||
15
|
||||
);
|
||||
|
||||
fprintf (stdout," ss <= 1'h%x; ",
|
||||
store_shift[n] == 40 ? 0 : 1);
|
||||
|
||||
fprintf (stdout," ep <= 2'h%x; ",
|
||||
extract_point[n] == 95 ? 0 :
|
||||
extract_point[n] == 100 ? 1 :
|
||||
extract_point[n] == 105 ? 2 : 0xf);
|
||||
|
||||
fprintf (stdout," end\n");
|
||||
if (n == 0x3f) fprintf (stdout,"\n");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fprintf (stdout,"Tallying\n");
|
||||
for (n=0; n<67; n++)
|
||||
{
|
||||
shift_used[n] = 0;
|
||||
}
|
||||
for (n=0; n<67; n++)
|
||||
{
|
||||
if (dat_shift[n] != -1)
|
||||
{
|
||||
shift_used[dat_shift[n]] = 1;
|
||||
}
|
||||
}
|
||||
int tally = 0;
|
||||
for (n=0; n<67; n++)
|
||||
{
|
||||
if (shift_used[n])
|
||||
{
|
||||
tally++;
|
||||
fprintf (stdout,"shift %d used\n",n);
|
||||
}
|
||||
}
|
||||
fprintf (stdout,"%d unique shifts\n",tally);
|
||||
return (0);
|
||||
}
|
82
Advanced Synthesis Cookbook/communication/gearbox_20_22.v
Normal file
82
Advanced Synthesis Cookbook/communication/gearbox_20_22.v
Normal file
@ -0,0 +1,82 @@
|
||||
// Copyright 2010 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`timescale 1 ps / 1 ps
|
||||
// baeckler - 12-14-2009
|
||||
|
||||
module gearbox_20_22 (
|
||||
input clk,
|
||||
|
||||
input odd, // select a shift by 1 bit of the data
|
||||
input drop2, // slip to lose 2 bits of data
|
||||
|
||||
input [19:0] din, // lsbit used first
|
||||
|
||||
output reg [21:0] dout,
|
||||
output reg dout_valid
|
||||
);
|
||||
|
||||
reg [19:0] din_r = 20'h0;
|
||||
reg extra_din_r = 1'b0;
|
||||
always @(posedge clk) begin
|
||||
if (odd) begin
|
||||
{extra_din_r,din_r} <= {din,extra_din_r};
|
||||
end
|
||||
else begin
|
||||
din_r <= din;
|
||||
end
|
||||
end
|
||||
|
||||
reg [3:0] gbstate = 4'b0 /* synthesis preserve */;
|
||||
always @(posedge clk) begin
|
||||
if (gbstate == 4'ha) gbstate <= 4'h0;
|
||||
else gbstate <= gbstate + (drop2 ? 2'd2 : 2'd1);
|
||||
end
|
||||
|
||||
reg [20 + 20 - 1:0] storage = 39'b0;
|
||||
reg dout_valid_i = 1'b0;
|
||||
always @(posedge clk) begin
|
||||
case (gbstate)
|
||||
4'h0: storage <= {20'b0,din_r};
|
||||
4'h1: storage <= {din_r,storage[19:0]};
|
||||
4'h2: storage <= {2'b0,din_r,storage[39:22]};
|
||||
4'h3: storage <= {4'b0,din_r,storage[37:22]};
|
||||
4'h4: storage <= {6'b0,din_r,storage[35:22]};
|
||||
4'h5: storage <= {8'b0,din_r,storage[33:22]};
|
||||
4'h6: storage <= {10'b0,din_r,storage[31:22]};
|
||||
4'h7: storage <= {12'b0,din_r,storage[29:22]};
|
||||
4'h8: storage <= {14'b0,din_r,storage[27:22]};
|
||||
4'h9: storage <= {16'b0,din_r,storage[25:22]};
|
||||
4'ha: storage <= {18'b0,din_r,storage[23:22]};
|
||||
default: storage <= {20'b0,din_r};
|
||||
endcase
|
||||
dout_valid_i <= |gbstate;
|
||||
end
|
||||
|
||||
initial dout = 22'b0;
|
||||
initial dout_valid = 1'b0;
|
||||
always @(posedge clk) begin
|
||||
dout_valid <= dout_valid_i;
|
||||
dout <= storage [21:0];
|
||||
end
|
||||
|
||||
endmodule
|
101
Advanced Synthesis Cookbook/communication/gearbox_20_66.v
Normal file
101
Advanced Synthesis Cookbook/communication/gearbox_20_66.v
Normal file
@ -0,0 +1,101 @@
|
||||
// Copyright 2010 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`timescale 1 ps / 1 ps
|
||||
// BLOCK 4,3
|
||||
// baeckler - 12-14-2009
|
||||
|
||||
module gearbox_20_66 (
|
||||
input clk,
|
||||
input slip_to_frame, // look for ethernet framing, [1:0] opposite
|
||||
input [19:0] din, // lsbit used first
|
||||
output reg [65:0] dout,
|
||||
output reg dout_valid
|
||||
);
|
||||
|
||||
wire [21:0] dout_22;
|
||||
wire dout_22_valid;
|
||||
|
||||
// framing control
|
||||
wire framed = ^dout[1:0];
|
||||
reg odd = 1'b0;
|
||||
reg drop2 = 1'b0;
|
||||
|
||||
// helper gearbox
|
||||
gearbox_20_22 gba (
|
||||
.clk(clk),
|
||||
|
||||
.odd(odd),
|
||||
.drop2(drop2),
|
||||
|
||||
.din(din), // lsbit used first
|
||||
.dout(dout_22),
|
||||
.dout_valid(dout_22_valid)
|
||||
);
|
||||
|
||||
// combine 3 words of 22 to one 66
|
||||
reg [1:0] gbstate = 0 /* synthesis preserve */;
|
||||
|
||||
wire [21:0] dout_mid,dout_low;
|
||||
assign {dout_mid,dout_low} = dout[43:0];
|
||||
|
||||
always @(posedge clk) begin
|
||||
dout_valid <= 1'b0;
|
||||
drop2 <= 1'b0;
|
||||
|
||||
case (gbstate)
|
||||
2'h0 : begin
|
||||
if (dout_22_valid) begin
|
||||
dout <= {22'h0,22'h0,dout_22};
|
||||
gbstate <= 2'h1;
|
||||
end
|
||||
end
|
||||
2'h1 : begin
|
||||
if (slip_to_frame & !framed) begin
|
||||
if (!odd) odd <= 1'b1;
|
||||
else begin
|
||||
drop2 <= 1'b1;
|
||||
odd <= 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
if (dout_22_valid) begin
|
||||
dout <= {22'h0,dout_22,dout_low};
|
||||
gbstate <= 2'h2;
|
||||
end
|
||||
end
|
||||
2'h2 : begin
|
||||
if (dout_22_valid) begin
|
||||
dout <= {dout_22,dout_mid,dout_low};
|
||||
gbstate <= 2'h0;
|
||||
dout_valid <= 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
2'h3 : begin
|
||||
// this is an illegal state. Recover
|
||||
gbstate <= 2'h0;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
117
Advanced Synthesis Cookbook/communication/gearbox_20_67.v
Normal file
117
Advanced Synthesis Cookbook/communication/gearbox_20_67.v
Normal file
@ -0,0 +1,117 @@
|
||||
// Copyright 2008 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 09-18-2008
|
||||
// Convert a steady 20 bit input stream into a
|
||||
// on and off 67 bit stream
|
||||
|
||||
module gearbox_20_67 (
|
||||
input clk,arst,
|
||||
input [19:0] din,
|
||||
input slip_to_frame, // 1=slip until you hit a properly framed word
|
||||
output [66:0] dout,
|
||||
output reg dout_valid
|
||||
);
|
||||
|
||||
reg loword_valid;
|
||||
reg [22:0] loword;
|
||||
|
||||
// worst case : want 23 bits, have 22, need to take on 20 more
|
||||
// therefore we need a 42 bit buffer
|
||||
reg [41:0] storage;
|
||||
reg [5:0] top_ptr;
|
||||
reg [2:0] schedule; // [0,1] 22 bits, [2] 23 bits
|
||||
reg mv_hi, mv_md;
|
||||
|
||||
reg [21:0] hiword,midword;
|
||||
assign dout = {hiword,midword,loword};
|
||||
|
||||
wire enough_bits = (top_ptr > 6'd22) || (!schedule[2] && top_ptr == 6'd22);
|
||||
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
top_ptr <= 0;
|
||||
storage <= 0;
|
||||
loword_valid <= 0;
|
||||
schedule <= 3'b001;
|
||||
mv_hi <= 0;
|
||||
mv_md <= 0;
|
||||
dout_valid <= 0;
|
||||
hiword <= 0;
|
||||
midword <= 0;
|
||||
loword <= 0;
|
||||
end
|
||||
else begin
|
||||
|
||||
// always take in new data - 20 bits
|
||||
storage <= {storage[21:0],din};
|
||||
loword_valid <= enough_bits;
|
||||
|
||||
// read 22 to hi, 22 to mid, 23 to low to form 67
|
||||
mv_hi <= schedule[0];
|
||||
mv_md <= schedule[1];
|
||||
dout_valid <= schedule[2] & enough_bits;
|
||||
|
||||
if (loword_valid && mv_hi) hiword <= loword[22:1];
|
||||
if (loword_valid && mv_md) midword <= loword[22:1];
|
||||
|
||||
// pull out 22 or 23 bits of data from the register
|
||||
case (top_ptr)
|
||||
6'd42: loword <= storage[41:19];
|
||||
6'd41: loword <= storage[40:18];
|
||||
6'd40: loword <= storage[39:17];
|
||||
6'd39: loword <= storage[38:16];
|
||||
6'd38: loword <= storage[37:15];
|
||||
6'd37: loword <= storage[36:14];
|
||||
6'd36: loword <= storage[35:13];
|
||||
6'd35: loword <= storage[34:12];
|
||||
6'd34: loword <= storage[33:11];
|
||||
6'd33: loword <= storage[32:10];
|
||||
6'd32: loword <= storage[31:9];
|
||||
6'd31: loword <= storage[30:8];
|
||||
6'd30: loword <= storage[29:7];
|
||||
6'd29: loword <= storage[28:6];
|
||||
6'd28: loword <= storage[27:5];
|
||||
6'd27: loword <= storage[26:4];
|
||||
6'd26: loword <= storage[25:3];
|
||||
6'd25: loword <= storage[24:2];
|
||||
6'd24: loword <= storage[23:1];
|
||||
6'd23: loword <= storage[22:0];
|
||||
6'd22: loword <= {storage[21:0],1'b0}; // 16 hex
|
||||
|
||||
default: loword <= 0; // not X, just for simulation sanity
|
||||
endcase
|
||||
|
||||
// we are always gaining 20 and losing either 0, 22 or 23 bits
|
||||
top_ptr <= top_ptr + (!enough_bits ? 6'd20 : (schedule[2] ? -6'd3 : -6'd2));
|
||||
|
||||
// when successful advance to next word
|
||||
if (enough_bits) schedule <= {schedule[1:0],schedule[2]};
|
||||
|
||||
// Optional slip to find properly framed words
|
||||
if (slip_to_frame & loword_valid & mv_hi & (~loword[21] ^ loword[20]))
|
||||
schedule <= 3'b001;
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
@ -0,0 +1,69 @@
|
||||
// Copyright 2009 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 09-19-2008
|
||||
|
||||
// Note : This testbench is for observation only.
|
||||
// See testbench gearbox_67_20_tb
|
||||
|
||||
module gearbox_20_67_tb ();
|
||||
|
||||
reg clk,arst;
|
||||
reg [19:0] din;
|
||||
wire [66:0] dout;
|
||||
wire dout_valid;
|
||||
|
||||
gearbox_20_67 dut (
|
||||
.*
|
||||
);
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
#1 arst = 1'b1;
|
||||
@(negedge clk) arst = 1'b0;
|
||||
end
|
||||
|
||||
always begin
|
||||
#5 clk = ~clk;
|
||||
end
|
||||
|
||||
reg [4*67-1:0] data_stream = {
|
||||
3'b010, 64'h1234567812345670,
|
||||
3'b010, 64'habcdef12abcdef11,
|
||||
3'b010, 64'h1234567812345679,
|
||||
3'b010, 64'habcdef12abcdef13
|
||||
};
|
||||
|
||||
integer n = 4*67-1;
|
||||
integer k;
|
||||
|
||||
always @(negedge clk) begin
|
||||
#2 if (!arst) begin
|
||||
din = 0;
|
||||
for (k=19;k>=0;k=k-1) begin
|
||||
din[k] = data_stream[n];
|
||||
if (n > 0) n = n - 1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
82
Advanced Synthesis Cookbook/communication/gearbox_32_33.v
Normal file
82
Advanced Synthesis Cookbook/communication/gearbox_32_33.v
Normal file
@ -0,0 +1,82 @@
|
||||
// Copyright 2009 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 01-08-2009
|
||||
|
||||
module gearbox_32_33 (
|
||||
input clk,arst,
|
||||
input [31:0] din, // bit 0 is sent first
|
||||
input din_valid,
|
||||
input din_slip, // drop bit 0 of the current din
|
||||
output [32:0] dout, // bit 0 is sent first
|
||||
output reg dout_valid
|
||||
);
|
||||
|
||||
reg [63:0] storage;
|
||||
reg [5:0] holding;
|
||||
|
||||
// make it explicit that holding will never be greater than 32
|
||||
// to help synthesis with the shifter
|
||||
wire [63:0] aligned_din = holding[5] ?
|
||||
{din,32'b0} :
|
||||
(din << holding[4:0]);
|
||||
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
holding <= 0;
|
||||
storage <= 0;
|
||||
dout_valid <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
dout_valid <= 1'b0;
|
||||
if (din_valid) begin
|
||||
|
||||
if (din_slip) begin
|
||||
// with 31 in and 33 out, holding decreases by 2, mod 33
|
||||
if (holding == 0) holding <= 6'd31;
|
||||
else if (holding == 1) holding <= 6'd32;
|
||||
else holding <= holding - 6'd2;
|
||||
end
|
||||
else begin
|
||||
// with 32 in and 33 out, holding decreases by 1, mod 33
|
||||
if (holding == 0) holding <= 6'd32;
|
||||
else holding <= holding - 6'd1;
|
||||
end
|
||||
|
||||
// when you are holding 32 bits there is no output,
|
||||
// don't shift the storage, otherwise remove the low
|
||||
// order 33 bits.
|
||||
storage <= (holding[5] ? storage : (storage >> 6'd33)) |
|
||||
(din_slip ? (aligned_din >> 1'b1) : aligned_din);
|
||||
|
||||
// the output will be valid unless we are not holding any
|
||||
// bits at all.
|
||||
dout_valid <= (holding == 0) ? 1'b0 :
|
||||
(din_slip && holding == 6'd1) ? 1'b0 :
|
||||
1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign dout = storage [32:0];
|
||||
|
||||
endmodule
|
95
Advanced Synthesis Cookbook/communication/gearbox_32_66.v
Normal file
95
Advanced Synthesis Cookbook/communication/gearbox_32_66.v
Normal file
@ -0,0 +1,95 @@
|
||||
// Copyright 2009 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 01-08-2009
|
||||
|
||||
module gearbox_32_66 (
|
||||
input clk,arst,
|
||||
input [31:0] din, // bit 0 is sent first
|
||||
input din_valid,
|
||||
input slip_to_frame,
|
||||
output [65:0] dout, // bit 0 is sent first
|
||||
output dout_valid,
|
||||
|
||||
// this is the number of bit slips used to find the lock
|
||||
// intended for debug / test
|
||||
output reg [6:0] slip_count
|
||||
);
|
||||
|
||||
////////////////////////////////////
|
||||
// workhorse 32 to 33 unit
|
||||
|
||||
reg gb33_slip;
|
||||
wire [32:0] gb33_dout;
|
||||
wire gb33_dout_valid;
|
||||
|
||||
gearbox_32_33 gb33 (
|
||||
.clk(clk),
|
||||
.arst(arst),
|
||||
.din(din), // bit 0 is sent first
|
||||
.din_valid(din_valid),
|
||||
.din_slip(gb33_slip), // drop bit 0 of the current din
|
||||
.dout(gb33_dout), // bit 0 is sent first
|
||||
.dout_valid(gb33_dout_valid)
|
||||
);
|
||||
wire correct_framing = ^gb33_dout[1:0];
|
||||
|
||||
////////////////////////////////////
|
||||
// alternate 33 bit halves with slip control
|
||||
|
||||
reg first_half;
|
||||
reg [32:0] prev_word;
|
||||
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
first_half <= 1'b1;
|
||||
gb33_slip <= 1'b0;
|
||||
prev_word <= 33'b0;
|
||||
slip_count <= 7'h0;
|
||||
end
|
||||
else begin
|
||||
if (din_valid) gb33_slip <= 1'b0;
|
||||
|
||||
// alternate reading 33 bit halves
|
||||
if (gb33_dout_valid) begin
|
||||
first_half <= ~first_half;
|
||||
if (first_half) prev_word <= gb33_dout;
|
||||
end
|
||||
|
||||
// when in search mode check the framing bits
|
||||
// they should be different if the alignment
|
||||
// is correct.
|
||||
|
||||
if (slip_to_frame) begin
|
||||
if (gb33_dout_valid & first_half & !correct_framing) begin
|
||||
// this isn't right, do a slip
|
||||
gb33_slip <= 1'b1;
|
||||
slip_count <= slip_count + 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign dout = {gb33_dout,prev_word};
|
||||
assign dout_valid = gb33_dout_valid & !first_half;
|
||||
|
||||
endmodule
|
130
Advanced Synthesis Cookbook/communication/gearbox_32_66_tb.sv
Normal file
130
Advanced Synthesis Cookbook/communication/gearbox_32_66_tb.sv
Normal file
@ -0,0 +1,130 @@
|
||||
// Copyright 2011 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module gearbox_32_66_tb ();
|
||||
|
||||
reg clk,arst;
|
||||
wire [31:0] din; // bit 0 is sent first
|
||||
reg din_valid = 1'b1;
|
||||
reg slip_to_frame = 1'b1;
|
||||
|
||||
////////////////////////////////////
|
||||
// provide some simple framed data
|
||||
|
||||
localparam SAMPLE_WORDS = 9;
|
||||
|
||||
reg [66*SAMPLE_WORDS-1:0] sample_data = {
|
||||
"be going", 2'b01,
|
||||
"y I must", 2'b01,
|
||||
"me to sa", 2'b01,
|
||||
"tay I ca", 2'b10,
|
||||
"cannot s", 2'b01,
|
||||
"going. I", 2'b01,
|
||||
"must be ", 2'b10,
|
||||
"Hello I ", 2'b01,
|
||||
64'hffff_ffff_ffff_ffff, 2'b10
|
||||
};
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (!arst) begin
|
||||
sample_data <= {
|
||||
sample_data[31:0],
|
||||
sample_data [66*SAMPLE_WORDS-1:32]
|
||||
};
|
||||
end
|
||||
end
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// the gearbox should be able to lock on ANY 32 bit
|
||||
// view of the sample data. Try 66 offsets.
|
||||
|
||||
wire [64*66-1:0] douts;
|
||||
wire [8*66-1:0] slip_counts;
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for (i=0; i<66; i=i+1)
|
||||
begin : dut_lp
|
||||
wire [65:0] dout; // bit 0 is sent first
|
||||
wire dout_valid;
|
||||
wire [6:0] slip_count;
|
||||
|
||||
// trim off the framing so the hex / ASCII is readable
|
||||
reg [64:0] trimmed_dout;
|
||||
always @(posedge clk) begin
|
||||
if (dout_valid) trimmed_dout <= dout >> 2;
|
||||
end
|
||||
|
||||
// test unit
|
||||
gearbox_32_66 dut (
|
||||
.clk,.arst,
|
||||
.din(sample_data[31+i:i]), // bit 0 is sent first
|
||||
.din_valid,
|
||||
.slip_to_frame,
|
||||
.dout, // bit 0 is sent first
|
||||
.dout_valid,
|
||||
.slip_count
|
||||
);
|
||||
|
||||
// gather up the outputs for observation
|
||||
assign douts [64*(i+1)-1:64*i] = trimmed_dout;
|
||||
assign slip_counts [8*(i+1)-1:8*i] = {1'b0,slip_count};
|
||||
end
|
||||
endgenerate
|
||||
|
||||
////////////////////////////////////
|
||||
// sanity check that the gearboxes find the appropriate
|
||||
// indices. They may be offset by 66 if they hit false
|
||||
// framing matches.
|
||||
|
||||
integer n;
|
||||
reg fail = 1'b0;
|
||||
initial begin
|
||||
#5000
|
||||
for (n=0; n<66; n=n+1) begin
|
||||
if (((2*66-n) % 66) != (slip_counts[8*(n+1)-1-:8] % 66))
|
||||
begin
|
||||
$display ("DUT %d is not at the expected slip index",n);
|
||||
fail = 1'b1;
|
||||
end
|
||||
end
|
||||
if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
////////////////////////////////////
|
||||
// clock driver
|
||||
|
||||
always begin
|
||||
#5 clk = ~clk;
|
||||
end
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
arst = 0;
|
||||
#1 arst = 1'b1;
|
||||
@(negedge clk) arst = 1'b0;
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
||||
|
83
Advanced Synthesis Cookbook/communication/gearbox_33_32.v
Normal file
83
Advanced Synthesis Cookbook/communication/gearbox_33_32.v
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright 2009 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 01-09-2008
|
||||
|
||||
module gearbox_33_32 (
|
||||
input clk,arst,
|
||||
|
||||
input [32:0] din,
|
||||
input din_valid,
|
||||
output din_ready,
|
||||
|
||||
output [31:0] dout,
|
||||
output reg dout_valid,
|
||||
input dout_ready
|
||||
);
|
||||
|
||||
reg [4:0] holding;
|
||||
reg holding_32;
|
||||
reg [63:0] storage;
|
||||
|
||||
assign din_ready = dout_ready & !holding_32;
|
||||
|
||||
// holding will never be >= 32
|
||||
wire [63:0] aligned_din = (din << holding);
|
||||
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
storage <= 0;
|
||||
holding <= 0;
|
||||
holding_32 <= 0;
|
||||
dout_valid <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
if (dout_ready) dout_valid <= 1'b0;
|
||||
|
||||
if (holding_32) begin
|
||||
holding <= 0;
|
||||
holding_32 <= 0;
|
||||
storage <= (storage >> 32);
|
||||
dout_valid <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
if (din_ready & din_valid) begin
|
||||
storage <= (storage >> 32) | aligned_din;
|
||||
|
||||
// when holding 31, 33 in, there are enough
|
||||
// bits for TWO words out.
|
||||
if (&holding) begin
|
||||
holding <= 0;
|
||||
holding_32 <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
holding <= holding + 1'b1;
|
||||
end
|
||||
dout_valid <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
assign dout = storage [31:0];
|
||||
|
||||
endmodule
|
@ -0,0 +1,74 @@
|
||||
// Copyright 2011 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module gearbox_33_32_tb ();
|
||||
|
||||
reg clk,arst;
|
||||
reg [32:0] din = 0;
|
||||
wire din_ready;
|
||||
wire [31:0] dout;
|
||||
|
||||
gearbox_33_32 dut (
|
||||
.*
|
||||
);
|
||||
|
||||
integer n;
|
||||
wire [32:0] recovered;
|
||||
wire recovered_valid;
|
||||
reg din_slip;
|
||||
initial begin
|
||||
din_slip = 1'b1;
|
||||
for (n=0; n<34; n=n+1) begin
|
||||
@(negedge clk);
|
||||
end
|
||||
din_slip = 1'b0;
|
||||
|
||||
end
|
||||
|
||||
gearbox_32_33 dut_b (
|
||||
.clk,.arst,
|
||||
.din(dout), // bit 0 is sent first
|
||||
.din_valid(1'b1),
|
||||
.din_slip(din_slip), // drop bit 0 of the current din
|
||||
.dout(recovered), // bit 0 is sent first
|
||||
.dout_valid(recovered_valid)
|
||||
);
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (din_ready) din <= din + 1'b1;
|
||||
end
|
||||
|
||||
////////////////////////////////////
|
||||
// clock driver
|
||||
|
||||
always begin
|
||||
#5 clk = ~clk;
|
||||
end
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
arst = 0;
|
||||
#1 arst = 1'b1;
|
||||
@(negedge clk) arst = 1'b0;
|
||||
end
|
||||
|
||||
endmodule
|
165
Advanced Synthesis Cookbook/communication/gearbox_40_66.v
Normal file
165
Advanced Synthesis Cookbook/communication/gearbox_40_66.v
Normal file
@ -0,0 +1,165 @@
|
||||
// Copyright 2010 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 40 in 66 out
|
||||
// baeckler - 07-21-2010
|
||||
|
||||
module gearbox_40_66 (
|
||||
input clk,
|
||||
input slip_to_frame, // look for the least significant 2 bits being opposite
|
||||
input [39:0] din, // lsbit first
|
||||
output [65:0] dout,
|
||||
output reg dout_valid,
|
||||
|
||||
output reg slipping, // pulses on position change
|
||||
output reg word_locked // lock detect with history
|
||||
);
|
||||
|
||||
initial dout_valid = 1'b0;
|
||||
|
||||
reg [5:0] gbstate = 0 /* synthesis preserve */;
|
||||
reg [103:0] stor = 0 /* synthesis preserve */;
|
||||
assign dout = stor[65:0];
|
||||
reg [39:0] din_r = 0;
|
||||
reg din_extra = 0;
|
||||
|
||||
// framing acquisition controls
|
||||
reg odd = 1'b0 /* synthesis preserve */; // select a 1 bit shift of the input data
|
||||
reg drop40 = 1'b0 /* synthesis preserve */; // slip by 1 input word
|
||||
|
||||
always @(posedge clk) begin
|
||||
din_extra <= din[39];
|
||||
din_r <= odd ? {din[38:0],din_extra} : din[39:0];
|
||||
|
||||
gbstate <= drop40 ? gbstate : (gbstate[5] ? 6'h0 : (gbstate + 1'b1));
|
||||
dout_valid <= 1'b0;
|
||||
|
||||
if (gbstate[5]) begin
|
||||
stor[65:26] <= din_r[39:0]; stor[25:0] <= stor[91:66]; dout_valid <= 1'b1;
|
||||
end // now holding 0
|
||||
else begin
|
||||
case (gbstate[4:0])
|
||||
5'h0 : begin stor[39:0] <= din_r[39:0]; end // now holding 40
|
||||
5'h1 : begin stor[79:40] <= din_r[39:0]; dout_valid <= 1'b1; end // now holding 14
|
||||
5'h2 : begin stor[53:14] <= din_r[39:0]; stor[13:0] <= stor[79:66]; end // now holding 54
|
||||
5'h3 : begin stor[93:54] <= din_r[39:0]; dout_valid <= 1'b1; end // now holding 28
|
||||
5'h4 : begin stor[67:28] <= din_r[39:0]; stor[27:0] <= stor[93:66]; dout_valid <= 1'b1; end // now holding 2
|
||||
5'h5 : begin stor[41:2] <= din_r[39:0]; stor[1:0] <= stor[67:66]; end // now holding 42
|
||||
5'h6 : begin stor[81:42] <= din_r[39:0]; dout_valid <= 1'b1; end // now holding 16
|
||||
5'h7 : begin stor[55:16] <= din_r[39:0]; stor[15:0] <= stor[81:66]; end // now holding 56
|
||||
5'h8 : begin stor[95:56] <= din_r[39:0]; dout_valid <= 1'b1; end // now holding 30
|
||||
5'h9 : begin stor[69:30] <= din_r[39:0]; stor[29:0] <= stor[95:66]; dout_valid <= 1'b1; end // now holding 4
|
||||
5'ha : begin stor[43:4] <= din_r[39:0]; stor[3:0] <= stor[69:66]; end // now holding 44
|
||||
5'hb : begin stor[83:44] <= din_r[39:0]; dout_valid <= 1'b1; end // now holding 18
|
||||
5'hc : begin stor[57:18] <= din_r[39:0]; stor[17:0] <= stor[83:66]; end // now holding 58
|
||||
5'hd : begin stor[97:58] <= din_r[39:0]; dout_valid <= 1'b1; end // now holding 32
|
||||
5'he : begin stor[71:32] <= din_r[39:0]; stor[31:0] <= stor[97:66]; dout_valid <= 1'b1; end // now holding 6
|
||||
5'hf : begin stor[45:6] <= din_r[39:0]; stor[5:0] <= stor[71:66]; end // now holding 46
|
||||
5'h10 : begin stor[85:46] <= din_r[39:0]; dout_valid <= 1'b1; end // now holding 20
|
||||
5'h11 : begin stor[59:20] <= din_r[39:0]; stor[19:0] <= stor[85:66]; end // now holding 60
|
||||
5'h12 : begin stor[99:60] <= din_r[39:0]; dout_valid <= 1'b1; end // now holding 34
|
||||
5'h13 : begin stor[73:34] <= din_r[39:0]; stor[33:0] <= stor[99:66]; dout_valid <= 1'b1; end // now holding 8
|
||||
5'h14 : begin stor[47:8] <= din_r[39:0]; stor[7:0] <= stor[73:66]; end // now holding 48
|
||||
5'h15 : begin stor[87:48] <= din_r[39:0]; dout_valid <= 1'b1; end // now holding 22
|
||||
5'h16 : begin stor[61:22] <= din_r[39:0]; stor[21:0] <= stor[87:66]; end // now holding 62
|
||||
5'h17 : begin stor[101:62] <= din_r[39:0]; dout_valid <= 1'b1; end // now holding 36
|
||||
5'h18 : begin stor[75:36] <= din_r[39:0]; stor[35:0] <= stor[101:66]; dout_valid <= 1'b1; end // now holding 10
|
||||
5'h19 : begin stor[49:10] <= din_r[39:0]; stor[9:0] <= stor[75:66]; end // now holding 50
|
||||
5'h1a : begin stor[89:50] <= din_r[39:0]; dout_valid <= 1'b1; end // now holding 24
|
||||
5'h1b : begin stor[63:24] <= din_r[39:0]; stor[23:0] <= stor[89:66]; end // now holding 64
|
||||
5'h1c : begin stor[103:64] <= din_r[39:0]; dout_valid <= 1'b1; end // now holding 38
|
||||
5'h1d : begin stor[77:38] <= din_r[39:0]; stor[37:0] <= stor[103:66]; dout_valid <= 1'b1; end // now holding 12
|
||||
5'h1e : begin stor[51:12] <= din_r[39:0]; stor[11:0] <= stor[77:66]; end // now holding 52
|
||||
5'h1f : begin stor[91:52] <= din_r[39:0]; dout_valid <= 1'b1; end // now holding 26
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// out pattern [32:0] 110110101101011010110101101011010
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// handle the details of slipping
|
||||
|
||||
reg [3:0] grace = 0 /* synthesis preserve */;
|
||||
wire bad_frame = ~^dout[1:0];
|
||||
|
||||
always @(posedge clk) begin
|
||||
drop40 <= 1'b0;
|
||||
slipping <= 1'b0;
|
||||
|
||||
if (slip_to_frame && bad_frame && !grace[3]) begin
|
||||
slipping <= 1'b1;
|
||||
if (odd) begin
|
||||
odd <= 1'b0;
|
||||
drop40 <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
odd <= 1'b1;
|
||||
end
|
||||
grace <= 4'b1111;
|
||||
end
|
||||
else begin
|
||||
grace <= {grace[2:0],1'b0};
|
||||
end
|
||||
end
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// word alignment control
|
||||
|
||||
reg [4:0] err_cnt = 1'b0;
|
||||
reg [5:0] wrd_cnt = 1'b0;
|
||||
reg wrd_cnt_max = 1'b0;
|
||||
initial word_locked = 1'b0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
wrd_cnt_max <= &wrd_cnt;
|
||||
|
||||
if (word_locked) begin
|
||||
if (dout_valid) begin
|
||||
wrd_cnt <= wrd_cnt + 1'b1;
|
||||
if (bad_frame) begin
|
||||
// count bad frames, saturate at 16
|
||||
if (!err_cnt[4]) err_cnt <= err_cnt + 1'b1;
|
||||
end
|
||||
if (wrd_cnt_max) begin
|
||||
// if there are more than 16 per 64 wrong lose lock
|
||||
if (err_cnt[4]) word_locked <= 1'b0;
|
||||
else err_cnt <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
else begin
|
||||
err_cnt <= 0;
|
||||
if (dout_valid) begin
|
||||
if (bad_frame) begin
|
||||
wrd_cnt <= 0;
|
||||
end
|
||||
else begin
|
||||
// if there are 64 good frames acquire lock
|
||||
wrd_cnt <= wrd_cnt + 1'b1;
|
||||
if (wrd_cnt_max) word_locked <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
239
Advanced Synthesis Cookbook/communication/gearbox_40_67.v
Normal file
239
Advanced Synthesis Cookbook/communication/gearbox_40_67.v
Normal file
@ -0,0 +1,239 @@
|
||||
// Copyright 2009 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 03-28-2008
|
||||
|
||||
module gearbox_40_67 (
|
||||
input clk,arst,
|
||||
input slip_to_frame,
|
||||
input [39:0] din,
|
||||
output reg [66:0] dout,
|
||||
output reg dout_valid
|
||||
);
|
||||
|
||||
// input reg
|
||||
reg [39:0] din_r;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) din_r <= 0;
|
||||
else din_r <= din;
|
||||
end
|
||||
|
||||
// decide when to use the slip permission
|
||||
// when the framing is wrong, and I haven't slipped in a few cycles
|
||||
reg [2:0] prev_slip;
|
||||
wire slip_now = prev_slip[0];
|
||||
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
prev_slip <= 0;
|
||||
end
|
||||
else begin
|
||||
prev_slip <= {prev_slip[1:0],1'b0};
|
||||
if (slip_to_frame) begin
|
||||
if (dout_valid & ~^dout[65:64]) begin
|
||||
// the framing is wrong, and I have a slip permit
|
||||
if (~|prev_slip) prev_slip[0] <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// where are we in the schedule?
|
||||
// to slip just fail to advance the phase once
|
||||
reg [6:0] phase;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) phase <= 0;
|
||||
else begin
|
||||
if (!slip_now) begin
|
||||
if (phase == 66) phase <= 0;
|
||||
else phase <= phase + 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// shift the input word left 0..13 inclusive to enter storage
|
||||
// at the right place
|
||||
reg [52:0] positioned_data;
|
||||
reg [3:0] dshift /* synthesis preserve */;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) positioned_data <= 0;
|
||||
else positioned_data <= din_r << dshift;
|
||||
end
|
||||
|
||||
// on every tick shift storage left by one of a couple of distance
|
||||
// choices, and merge in the positioned data
|
||||
reg [105:0] storage;
|
||||
reg [1:0] sshift /* synthesis preserve */;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) storage <= 0;
|
||||
else begin
|
||||
case (sshift)
|
||||
2'b00 : storage <= (storage << 33) | positioned_data;
|
||||
2'b01 : storage <= (storage << 34) | positioned_data;
|
||||
2'b10 : storage <= (storage << 40) | positioned_data;
|
||||
2'b11 : storage <= (storage << 47) | positioned_data;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// extract an output word from one of a couple of choices
|
||||
reg [1:0] epoint /* synthesis preserve */;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
dout <= 0;
|
||||
dout_valid <= 0;
|
||||
end
|
||||
else begin
|
||||
case (epoint)
|
||||
2'b00: begin
|
||||
dout_valid <= 1'b0;
|
||||
dout <= 0;
|
||||
end
|
||||
2'b01: begin
|
||||
dout_valid <= 1'b1;
|
||||
dout <= storage [78:78-66];
|
||||
end
|
||||
2'b10: begin
|
||||
dout_valid <= 1'b1;
|
||||
dout <= storage [92:92-66];
|
||||
end
|
||||
2'b11: begin
|
||||
dout_valid <= 1'b1;
|
||||
dout <= storage [105:105-66];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// The schedule - expected to map into one 6LUT per output bit
|
||||
// if it goes to ROM be sure to suppress
|
||||
reg [3:0] ds /* synthesis preserve */;
|
||||
reg [3:0] dsalt;
|
||||
reg [1:0] ss,ep /* synthesis preserve */;
|
||||
reg [1:0] ssalt,epalt;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
ds <= 0;
|
||||
dsalt <= 0;
|
||||
ss <= 0;
|
||||
ssalt <= 0;
|
||||
ep <= 0;
|
||||
epalt <= 0;
|
||||
end
|
||||
else begin
|
||||
case (phase[5:0])
|
||||
6'h00 : begin ds <= 4'hd; ss <= 2'h3; ep <= 2'h1; end
|
||||
6'h01 : begin ds <= 4'hd; ss <= 2'h3; ep <= 2'h0; end
|
||||
6'h02 : begin ds <= 4'hd; ss <= 2'h2; ep <= 2'h2; end
|
||||
6'h03 : begin ds <= 4'h7; ss <= 2'h2; ep <= 2'h0; end
|
||||
6'h04 : begin ds <= 4'h0; ss <= 2'h1; ep <= 2'h3; end
|
||||
6'h05 : begin ds <= 4'h0; ss <= 2'h0; ep <= 2'h0; end
|
||||
6'h06 : begin ds <= 4'h7; ss <= 2'h2; ep <= 2'h3; end
|
||||
6'h07 : begin ds <= 4'h1; ss <= 2'h3; ep <= 2'h1; end
|
||||
6'h08 : begin ds <= 4'h8; ss <= 2'h1; ep <= 2'h0; end
|
||||
6'h09 : begin ds <= 4'h1; ss <= 2'h3; ep <= 2'h2; end
|
||||
6'h0a : begin ds <= 4'h1; ss <= 2'h0; ep <= 2'h0; end
|
||||
6'h0b : begin ds <= 4'h8; ss <= 2'h2; ep <= 2'h3; end
|
||||
6'h0c : begin ds <= 4'h2; ss <= 2'h3; ep <= 2'h1; end
|
||||
6'h0d : begin ds <= 4'h9; ss <= 2'h1; ep <= 2'h0; end
|
||||
6'h0e : begin ds <= 4'h2; ss <= 2'h3; ep <= 2'h2; end
|
||||
6'h0f : begin ds <= 4'h2; ss <= 2'h0; ep <= 2'h0; end
|
||||
6'h10 : begin ds <= 4'h9; ss <= 2'h2; ep <= 2'h3; end
|
||||
6'h11 : begin ds <= 4'h3; ss <= 2'h3; ep <= 2'h1; end
|
||||
6'h12 : begin ds <= 4'ha; ss <= 2'h1; ep <= 2'h0; end
|
||||
6'h13 : begin ds <= 4'h3; ss <= 2'h3; ep <= 2'h2; end
|
||||
6'h14 : begin ds <= 4'h3; ss <= 2'h0; ep <= 2'h0; end
|
||||
6'h15 : begin ds <= 4'ha; ss <= 2'h2; ep <= 2'h3; end
|
||||
6'h16 : begin ds <= 4'h4; ss <= 2'h3; ep <= 2'h1; end
|
||||
6'h17 : begin ds <= 4'hb; ss <= 2'h1; ep <= 2'h0; end
|
||||
6'h18 : begin ds <= 4'h4; ss <= 2'h3; ep <= 2'h2; end
|
||||
6'h19 : begin ds <= 4'h4; ss <= 2'h0; ep <= 2'h0; end
|
||||
6'h1a : begin ds <= 4'hb; ss <= 2'h2; ep <= 2'h3; end
|
||||
6'h1b : begin ds <= 4'h5; ss <= 2'h3; ep <= 2'h1; end
|
||||
6'h1c : begin ds <= 4'hc; ss <= 2'h1; ep <= 2'h0; end
|
||||
6'h1d : begin ds <= 4'h5; ss <= 2'h3; ep <= 2'h2; end
|
||||
6'h1e : begin ds <= 4'h5; ss <= 2'h0; ep <= 2'h0; end
|
||||
6'h1f : begin ds <= 4'hc; ss <= 2'h2; ep <= 2'h3; end
|
||||
6'h20 : begin ds <= 4'h6; ss <= 2'h3; ep <= 2'h1; end
|
||||
6'h21 : begin ds <= 4'hd; ss <= 2'h1; ep <= 2'h0; end
|
||||
6'h22 : begin ds <= 4'h6; ss <= 2'h3; ep <= 2'h2; end
|
||||
6'h23 : begin ds <= 4'h6; ss <= 2'h0; ep <= 2'h0; end
|
||||
6'h24 : begin ds <= 4'hd; ss <= 2'h2; ep <= 2'h3; end
|
||||
6'h25 : begin ds <= 4'h7; ss <= 2'h3; ep <= 2'h1; end
|
||||
6'h26 : begin ds <= 4'h7; ss <= 2'h1; ep <= 2'h0; end
|
||||
6'h27 : begin ds <= 4'h7; ss <= 2'h2; ep <= 2'h2; end
|
||||
6'h28 : begin ds <= 4'h7; ss <= 2'h2; ep <= 2'h0; end
|
||||
6'h29 : begin ds <= 4'h1; ss <= 2'h2; ep <= 2'h3; end
|
||||
6'h2a : begin ds <= 4'h8; ss <= 2'h1; ep <= 2'h1; end
|
||||
6'h2b : begin ds <= 4'h8; ss <= 2'h3; ep <= 2'h0; end
|
||||
6'h2c : begin ds <= 4'h8; ss <= 2'h2; ep <= 2'h2; end
|
||||
6'h2d : begin ds <= 4'h8; ss <= 2'h2; ep <= 2'h0; end
|
||||
6'h2e : begin ds <= 4'h2; ss <= 2'h2; ep <= 2'h3; end
|
||||
6'h2f : begin ds <= 4'h9; ss <= 2'h1; ep <= 2'h1; end
|
||||
6'h30 : begin ds <= 4'h9; ss <= 2'h3; ep <= 2'h0; end
|
||||
6'h31 : begin ds <= 4'h9; ss <= 2'h2; ep <= 2'h2; end
|
||||
6'h32 : begin ds <= 4'h9; ss <= 2'h2; ep <= 2'h0; end
|
||||
6'h33 : begin ds <= 4'h3; ss <= 2'h2; ep <= 2'h3; end
|
||||
6'h34 : begin ds <= 4'ha; ss <= 2'h1; ep <= 2'h1; end
|
||||
6'h35 : begin ds <= 4'ha; ss <= 2'h3; ep <= 2'h0; end
|
||||
6'h36 : begin ds <= 4'ha; ss <= 2'h2; ep <= 2'h2; end
|
||||
6'h37 : begin ds <= 4'ha; ss <= 2'h2; ep <= 2'h0; end
|
||||
6'h38 : begin ds <= 4'h4; ss <= 2'h2; ep <= 2'h3; end
|
||||
6'h39 : begin ds <= 4'hb; ss <= 2'h1; ep <= 2'h1; end
|
||||
6'h3a : begin ds <= 4'hb; ss <= 2'h3; ep <= 2'h0; end
|
||||
6'h3b : begin ds <= 4'hb; ss <= 2'h2; ep <= 2'h2; end
|
||||
6'h3c : begin ds <= 4'hb; ss <= 2'h2; ep <= 2'h0; end
|
||||
6'h3d : begin ds <= 4'h5; ss <= 2'h2; ep <= 2'h3; end
|
||||
6'h3e : begin ds <= 4'hc; ss <= 2'h1; ep <= 2'h1; end
|
||||
6'h3f : begin ds <= 4'hc; ss <= 2'h3; ep <= 2'h0; end
|
||||
endcase
|
||||
|
||||
case (phase[1:0])
|
||||
2'h0 : begin dsalt <= 4'hc; ssalt <= 2'h2; epalt <= 2'h2; end
|
||||
2'h1 : begin dsalt <= 4'hc; ssalt <= 2'h2; epalt <= 2'h0; end
|
||||
2'h2 : begin dsalt <= 4'h6; ssalt <= 2'h2; epalt <= 2'h3; end
|
||||
|
||||
// this one is actually don't care
|
||||
// selected to minimize
|
||||
2'h3 : begin dsalt <= 4'h6; ssalt <= 2'h2; epalt <= 2'h3; end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// phase 64,5,6 use the alternate schedule
|
||||
reg use_alt;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
sshift <= 0;
|
||||
dshift <= 0;
|
||||
epoint <= 0;
|
||||
use_alt <= 0;
|
||||
end
|
||||
else begin
|
||||
sshift <= use_alt ? ssalt : ss;
|
||||
dshift <= use_alt ? dsalt : ds;
|
||||
epoint <= use_alt ? epalt : ep;
|
||||
use_alt <= phase[6];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
146
Advanced Synthesis Cookbook/communication/gearbox_40_67_tb.sv
Normal file
146
Advanced Synthesis Cookbook/communication/gearbox_40_67_tb.sv
Normal file
@ -0,0 +1,146 @@
|
||||
// Copyright 2011 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module gearbox_40_67_tb ();
|
||||
|
||||
reg clk,arst;
|
||||
|
||||
localparam TEST_SAMPLES = 16;
|
||||
reg [TEST_SAMPLES*67-1:0] test = {
|
||||
3'b010,64'h00000000_00000000,
|
||||
3'b110,64'hffffffff_ffffffff,
|
||||
3'b010,64'h02234567_89abcdef,
|
||||
3'b110,64'h03234567_89abcdef,
|
||||
3'b010,64'h04234567_89abcdef,
|
||||
3'b110,64'h05234567_8900cdef,
|
||||
3'b010,64'h06234567_8901cdef,
|
||||
3'b010,64'h07234567_8902cdef,
|
||||
3'b110,64'h08234567_8903cdef,
|
||||
3'b010,64'h09234567_8904cdef,
|
||||
3'b010,64'h0a234567_8905cdef,
|
||||
3'b110,64'h0b234567_8906cdef,
|
||||
3'b010,64'h0c234567_8907cdef,
|
||||
3'b110,64'h0d234567_89abcd99,
|
||||
3'b010,64'h0e234567_89abcdef,
|
||||
3'b110,64'h0f234567_89abcdef
|
||||
};
|
||||
|
||||
reg [TEST_SAMPLES*67-1:0] expected;
|
||||
|
||||
//////////////////////////////////////////
|
||||
// DUTs
|
||||
//////////////////////////////////////////
|
||||
|
||||
wire din_ready;
|
||||
wire [39:0] mid;
|
||||
|
||||
gearbox_67_40 dut_a (
|
||||
.clk,.arst,
|
||||
.din(test[66:0]),
|
||||
.din_ready,
|
||||
.dout (mid)
|
||||
);
|
||||
|
||||
// recover the sender side data for observation
|
||||
integer holding = 41;
|
||||
reg [100:0] history;
|
||||
reg [66:0] recovered;
|
||||
always @(posedge clk) begin
|
||||
#1
|
||||
history = (history << 40) | mid;
|
||||
holding = holding + 40;
|
||||
if (holding >= 67) begin
|
||||
recovered = history >> (holding-67);
|
||||
holding = holding - 67;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (din_ready) test <=
|
||||
{test [(TEST_SAMPLES-1)*67-1:0],
|
||||
test[TEST_SAMPLES*67-1:(TEST_SAMPLES-1)*67]};
|
||||
end
|
||||
|
||||
wire [66:0] dout;
|
||||
wire dout_valid;
|
||||
|
||||
gearbox_40_67 dut_b (
|
||||
.clk,.arst,
|
||||
.slip_to_frame(1'b1),
|
||||
.din(mid),
|
||||
.dout,
|
||||
.dout_valid
|
||||
);
|
||||
|
||||
//////////////////////////////////////////
|
||||
// Follow the recovered data
|
||||
//////////////////////////////////////////
|
||||
|
||||
initial expected = test;
|
||||
wire match = (dout_valid & (dout == expected[66:0]));
|
||||
|
||||
integer match_count = 0;
|
||||
integer trial_count = 0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
#1 if (match) begin
|
||||
expected <=
|
||||
{expected [(TEST_SAMPLES-1)*67-1:0],
|
||||
expected[TEST_SAMPLES*67-1:(TEST_SAMPLES-1)*67]};
|
||||
match_count <= match_count + 1;
|
||||
end
|
||||
if (dout_valid) trial_count <= trial_count + 1'b1;
|
||||
end
|
||||
|
||||
initial begin
|
||||
#400 // allow some time to lock
|
||||
@(negedge clk) trial_count = 0;
|
||||
match_count = 0;
|
||||
#100000
|
||||
$display ("%d trials %d matches\n",trial_count,match_count);
|
||||
|
||||
// Note : If there is a problem these will deviate
|
||||
// wildly. Off by one is OK, but it doesn't seem
|
||||
// to happen in this test.
|
||||
|
||||
if (trial_count == match_count) begin
|
||||
$display ("PASS");
|
||||
end
|
||||
$stop();
|
||||
end
|
||||
|
||||
//////////////////////////////////////////
|
||||
// clock driver
|
||||
//////////////////////////////////////////
|
||||
|
||||
always begin
|
||||
#5 clk = ~clk;
|
||||
end
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
arst = 0;
|
||||
#1 arst = 1;
|
||||
@(negedge clk) arst = 0;
|
||||
end
|
||||
|
||||
endmodule
|
111
Advanced Synthesis Cookbook/communication/gearbox_66_20.v
Normal file
111
Advanced Synthesis Cookbook/communication/gearbox_66_20.v
Normal file
@ -0,0 +1,111 @@
|
||||
// Copyright 2010 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`timescale 1 ps / 1 ps
|
||||
// BLOCK 5,4
|
||||
// baeckler - 12-14-2009
|
||||
|
||||
module gearbox_66_20 (
|
||||
input clk,
|
||||
input sclr, // fixes the state, although not the data registers for reduced fanout
|
||||
input [65:0] din, // lsbit sent first
|
||||
output reg din_ack,
|
||||
output reg [19:0] dout
|
||||
);
|
||||
|
||||
reg [65:0] din_r = 0 /* synthesis preserve */;
|
||||
always @(posedge clk) begin
|
||||
if (din_ack) din_r <= din;
|
||||
end
|
||||
|
||||
reg [5:0] gbstate = 0 /* synthesis preserve */;
|
||||
always @(posedge clk) begin
|
||||
if (gbstate[5] | sclr) gbstate <= 6'b0;
|
||||
else gbstate <= gbstate + 1'b1;
|
||||
end
|
||||
|
||||
reg [3:0] muxop = 0 /* synthesis preserve */;
|
||||
always @(posedge clk) begin
|
||||
case (gbstate)
|
||||
6'h0 : muxop <= 4'h1; // (66 in to position shl 0) 20 out, residue 46
|
||||
6'h1 : muxop <= 4'h0; // 20 out, residue 26
|
||||
6'h2 : muxop <= 4'h0; // 20 out, residue 6
|
||||
6'h3 : muxop <= 4'h4; // (66 in to position shl 6) 20 out, residue 52
|
||||
6'h4 : muxop <= 4'h0; // 20 out, residue 32
|
||||
6'h5 : muxop <= 4'h0; // 20 out, residue 12
|
||||
6'h6 : muxop <= 4'h7; // (66 in to position shl 12) 20 out, residue 58
|
||||
6'h7 : muxop <= 4'h0; // 20 out, residue 38
|
||||
6'h8 : muxop <= 4'h0; // 20 out, residue 18
|
||||
6'h9 : muxop <= 4'ha; // (66 in to position shl 18) 20 out, residue 64
|
||||
6'ha : muxop <= 4'h0; // 20 out, residue 44
|
||||
6'hb : muxop <= 4'h0; // 20 out, residue 24
|
||||
6'hc : muxop <= 4'h0; // 20 out, residue 4
|
||||
6'hd : muxop <= 4'h3; // (66 in to position shl 4) 20 out, residue 50
|
||||
6'he : muxop <= 4'h0; // 20 out, residue 30
|
||||
6'hf : muxop <= 4'h0; // 20 out, residue 10
|
||||
6'h10 : muxop <= 4'h6; // (66 in to position shl 10) 20 out, residue 56
|
||||
6'h11 : muxop <= 4'h0; // 20 out, residue 36
|
||||
6'h12 : muxop <= 4'h0; // 20 out, residue 16
|
||||
6'h13 : muxop <= 4'h9; // (66 in to position shl 16) 20 out, residue 62
|
||||
6'h14 : muxop <= 4'h0; // 20 out, residue 42
|
||||
6'h15 : muxop <= 4'h0; // 20 out, residue 22
|
||||
6'h16 : muxop <= 4'h0; // 20 out, residue 2
|
||||
6'h17 : muxop <= 4'h2; // (66 in to position shl 2) 20 out, residue 48
|
||||
6'h18 : muxop <= 4'h0; // 20 out, residue 28
|
||||
6'h19 : muxop <= 4'h0; // 20 out, residue 8
|
||||
6'h1a : muxop <= 4'h5; // (66 in to position shl 8) 20 out, residue 54
|
||||
6'h1b : muxop <= 4'h0; // 20 out, residue 34
|
||||
6'h1c : muxop <= 4'h0; // 20 out, residue 14
|
||||
6'h1d : muxop <= 4'h8; // (66 in to position shl 14) 20 out, residue 60
|
||||
6'h1e : muxop <= 4'h0; // 20 out, residue 40
|
||||
6'h1f : muxop <= 4'h0; // 20 out, residue 20
|
||||
6'h20 : muxop <= 4'h0; // 20 out, residue 0
|
||||
default : muxop <= 4'h0;
|
||||
endcase
|
||||
end
|
||||
|
||||
reg [18+66-1:0] storage = 0;
|
||||
always @(posedge clk) begin
|
||||
if (sclr) din_ack <= 1'b0;
|
||||
else din_ack <= |muxop;
|
||||
case (muxop)
|
||||
4'h0 : storage <= {18'h0,storage[83:20]};
|
||||
4'h1 : storage <= {18'h0,din_r};
|
||||
4'h2 : storage <= {16'b0,din_r,storage[21:20]}; // din shl 2
|
||||
4'h3 : storage <= {14'b0,din_r,storage[23:20]}; // din shl 4
|
||||
4'h4 : storage <= {12'b0,din_r,storage[25:20]}; // din shl 6
|
||||
4'h5 : storage <= {10'b0,din_r,storage[27:20]}; // din shl 8
|
||||
4'h6 : storage <= {8'b0,din_r,storage[29:20]}; // din shl 10
|
||||
4'h7 : storage <= {6'b0,din_r,storage[31:20]}; // din shl 12
|
||||
4'h8 : storage <= {4'b0,din_r,storage[33:20]}; // din shl 14
|
||||
4'h9 : storage <= {2'b0,din_r,storage[35:20]}; // din shl 16
|
||||
4'ha : storage <= {din_r,storage[37:20]}; // din shl 18
|
||||
default : storage <= {18'h0,storage[83:20]};
|
||||
endcase
|
||||
end
|
||||
|
||||
initial dout = 20'b0;
|
||||
always @(posedge clk) begin
|
||||
dout <= storage [19:0];
|
||||
end
|
||||
|
||||
endmodule
|
@ -0,0 +1,96 @@
|
||||
// Copyright 2010 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`timescale 1 ps / 1 ps
|
||||
module gearbox_66_20_tb ();
|
||||
|
||||
reg clk = 0 ;
|
||||
reg [65:0] din = 0;
|
||||
wire din_ack;
|
||||
wire [19:0] dout_20;
|
||||
|
||||
gearbox_66_20 dut_a (
|
||||
.clk,
|
||||
.sclr(1'b0),
|
||||
.din, // lsbit sent first
|
||||
.din_ack,
|
||||
.dout(dout_20)
|
||||
);
|
||||
|
||||
reg [39:0] history;
|
||||
always @(posedge clk) begin
|
||||
history <= (history >> 20) | (dout_20 << 20);
|
||||
end
|
||||
wire [19:0] shifted_dout_20 = history >> 3;
|
||||
|
||||
wire [65:0] recovered;
|
||||
wire recovered_valid;
|
||||
|
||||
gearbox_20_66 dut_b (
|
||||
.clk,
|
||||
.slip_to_frame (1'b1), // look for ethernet framing, [1:0] opposite
|
||||
.din(shifted_dout_20), // lsbit used first
|
||||
.dout(recovered),
|
||||
.dout_valid(recovered_valid)
|
||||
);
|
||||
|
||||
reg [63:0] payload;
|
||||
initial payload = {$random,$random};
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (din_ack) begin
|
||||
din <= {payload,2'b10};
|
||||
payload <= {payload[62:0],payload[63]};
|
||||
end
|
||||
end
|
||||
|
||||
reg [65:0] last_recover = 0;
|
||||
reg recover_err = 1'b1;
|
||||
always @(posedge clk) begin
|
||||
if (recovered_valid) begin
|
||||
last_recover <= recovered;
|
||||
recover_err <= (recovered[65:2] !== {last_recover[64:2],last_recover[65]}) ?
|
||||
1'b1 : 1'b0;
|
||||
end
|
||||
end
|
||||
|
||||
always begin
|
||||
#5 clk = ~clk;
|
||||
end
|
||||
|
||||
reg grace = 1'b1;
|
||||
initial begin
|
||||
grace = 1'b1;
|
||||
#10000 grace = 1'b0;
|
||||
end
|
||||
|
||||
reg fail = 1'b0;
|
||||
always @(posedge clk) begin
|
||||
if (!grace & recover_err) fail <= 1'b1;
|
||||
end
|
||||
|
||||
initial begin
|
||||
#100000 if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
endmodule
|
67
Advanced Synthesis Cookbook/communication/gearbox_66_32.v
Normal file
67
Advanced Synthesis Cookbook/communication/gearbox_66_32.v
Normal file
@ -0,0 +1,67 @@
|
||||
// Copyright 2009 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 01-09-2009
|
||||
|
||||
module gearbox_66_32 (
|
||||
input clk,arst,
|
||||
input [65:0] din,
|
||||
input din_valid,
|
||||
output din_ready,
|
||||
output[31:0] dout,
|
||||
input dout_ready,
|
||||
output dout_valid
|
||||
);
|
||||
|
||||
///////////////////////////////
|
||||
// Cut in half to 33 bit words
|
||||
|
||||
wire [32:0] gb33_dout;
|
||||
wire gb33_dout_ready, gb33_dout_valid;
|
||||
|
||||
two_to_one tto (
|
||||
.clk(clk),
|
||||
.arst(arst),
|
||||
.din(din),
|
||||
.din_valid(din_valid),
|
||||
.din_ready(din_ready),
|
||||
.dout(gb33_dout),
|
||||
.dout_ready(gb33_dout_ready),
|
||||
.dout_valid(gb33_dout_valid)
|
||||
);
|
||||
defparam tto .WORD_LEN = 33;
|
||||
|
||||
///////////////////////////////
|
||||
// Convert 33 to 32
|
||||
|
||||
gearbox_33_32 gb32 (
|
||||
.clk(clk),
|
||||
.arst(arst),
|
||||
.din(gb33_dout),
|
||||
.din_valid(gb33_dout_valid),
|
||||
.din_ready(gb33_dout_ready),
|
||||
.dout(dout),
|
||||
.dout_ready(dout_ready),
|
||||
.dout_valid(dout_valid)
|
||||
);
|
||||
|
||||
endmodule
|
142
Advanced Synthesis Cookbook/communication/gearbox_66_32_tb.sv
Normal file
142
Advanced Synthesis Cookbook/communication/gearbox_66_32_tb.sv
Normal file
@ -0,0 +1,142 @@
|
||||
// Copyright 2011 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module gearbox_66_32_tb ();
|
||||
|
||||
reg clk,arst;
|
||||
reg slip_to_frame = 1'b1;
|
||||
|
||||
////////////////////////////////////
|
||||
// provide some simple framed data
|
||||
|
||||
localparam SAMPLE_WORDS = 9;
|
||||
|
||||
reg [66*SAMPLE_WORDS-1:0] sample_data = {
|
||||
"be going", 2'b01,
|
||||
"y I must", 2'b01,
|
||||
"me to sa", 2'b01,
|
||||
"tay I ca", 2'b10,
|
||||
"cannot s", 2'b01,
|
||||
"going. I", 2'b01,
|
||||
"must be ", 2'b10,
|
||||
"Hello I ", 2'b01,
|
||||
64'hffff_ffff_ffff_ffff, 2'b10
|
||||
};
|
||||
|
||||
wire din_ready;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (!arst) begin
|
||||
if (din_ready) begin
|
||||
sample_data <= {
|
||||
sample_data[65:0],
|
||||
sample_data [66*SAMPLE_WORDS-1:66]
|
||||
};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
wire [65:0] sample_word_66 = sample_data[65:0];
|
||||
wire [63:0] trimmed_sample_word_66 = sample_word_66 >> 2;
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// DUT - convert the 66 bit words into 32 bits
|
||||
|
||||
wire [31:0] sample_word_32;
|
||||
wire sample_word_valid;
|
||||
|
||||
gearbox_66_32 dut (
|
||||
.clk,
|
||||
.arst,
|
||||
.din(sample_word_66),
|
||||
.din_valid(1'b1),
|
||||
.din_ready,
|
||||
.dout(sample_word_32),
|
||||
.dout_valid(sample_word_valid),
|
||||
.dout_ready(1'b1)
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// recover the 66 to check
|
||||
|
||||
reg fail = 0;
|
||||
reg [4:0] flushing;
|
||||
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) flushing <= 0;
|
||||
else if (~&flushing) flushing <= flushing + 1'b1;
|
||||
end
|
||||
|
||||
wire [65:0] recovered_66;
|
||||
wire recovered_66_valid;
|
||||
reg [63:0] trimmed_dout;
|
||||
always @(posedge clk) begin
|
||||
if (recovered_66_valid) trimmed_dout <= recovered_66 >> 2;
|
||||
|
||||
if (&flushing &&
|
||||
trimmed_dout[63:56] !== "b" &&
|
||||
trimmed_dout[63:56] !== "y" &&
|
||||
trimmed_dout[63:56] !== "m" &&
|
||||
trimmed_dout[63:56] !== "t" &&
|
||||
trimmed_dout[63:56] !== "c" &&
|
||||
trimmed_dout[63:56] !== "g" &&
|
||||
trimmed_dout[63:56] !== "H" &&
|
||||
trimmed_dout[63:56] !== 8'hff)
|
||||
begin
|
||||
$display ("Bad recovered data at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
end
|
||||
|
||||
wire [6:0] slip_count;
|
||||
|
||||
gearbox_32_66 rec (
|
||||
.clk,.arst,
|
||||
.din(sample_word_32), // bit 0 is sent first
|
||||
.din_valid(sample_word_valid),
|
||||
.slip_to_frame,
|
||||
.dout(recovered_66), // bit 0 is sent first
|
||||
.dout_valid(recovered_66_valid),
|
||||
.slip_count
|
||||
);
|
||||
|
||||
////////////////////////////////////
|
||||
// clock driver
|
||||
|
||||
initial begin
|
||||
#100000 if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
always begin
|
||||
#5 clk = ~clk;
|
||||
end
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
arst = 0;
|
||||
#1 arst = 1'b1;
|
||||
@(negedge clk) arst = 1'b0;
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
113
Advanced Synthesis Cookbook/communication/gearbox_66_40.v
Normal file
113
Advanced Synthesis Cookbook/communication/gearbox_66_40.v
Normal file
@ -0,0 +1,113 @@
|
||||
// Copyright 2010 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// 66 in 40 out
|
||||
// baeckler - 07-21-2010
|
||||
|
||||
module gearbox_66_40 (
|
||||
input clk,
|
||||
input sclr, // fixes the state, not the data for min fanout
|
||||
input [65:0] din, // lsbit first
|
||||
output reg din_ack,
|
||||
output reg din_pre_ack,
|
||||
output reg din_pre2_ack,
|
||||
output [39:0] dout
|
||||
);
|
||||
|
||||
reg [5:0] gbstate = 0 /* synthesis preserve */;
|
||||
reg [103:0] stor = 0 /* synthesis preserve */;
|
||||
assign dout = stor[39:0];
|
||||
reg [65:0] din_r = 0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
din_r <= din[65:0];
|
||||
|
||||
gbstate <= (sclr | gbstate[5]) ? 6'h0 : (gbstate + 1'b1);
|
||||
|
||||
if (gbstate[5]) begin
|
||||
stor <= {40'h0,stor[103:40]}; // holding 0
|
||||
end
|
||||
else begin
|
||||
case (gbstate[4:0])
|
||||
5'h0 : begin stor[65:0] <= din[65:0]; end // holding 26
|
||||
5'h1 : begin stor[91:26] <= din[65:0]; stor[25:0] <= stor[65:40]; end // holding 52
|
||||
5'h2 : begin stor <= {40'h0,stor[103:40]}; end // holding 12
|
||||
5'h3 : begin stor[77:12] <= din[65:0]; stor[11:0] <= stor[51:40]; end // holding 38
|
||||
5'h4 : begin stor[103:38] <= din[65:0]; stor[37:0] <= stor[77:40]; end // holding 64
|
||||
5'h5 : begin stor <= {40'h0,stor[103:40]}; end // holding 24
|
||||
5'h6 : begin stor[89:24] <= din[65:0]; stor[23:0] <= stor[63:40]; end // holding 50
|
||||
5'h7 : begin stor <= {40'h0,stor[103:40]}; end // holding 10
|
||||
5'h8 : begin stor[75:10] <= din[65:0]; stor[9:0] <= stor[49:40]; end // holding 36
|
||||
5'h9 : begin stor[101:36] <= din[65:0]; stor[35:0] <= stor[75:40]; end // holding 62
|
||||
5'ha : begin stor <= {40'h0,stor[103:40]}; end // holding 22
|
||||
5'hb : begin stor[87:22] <= din[65:0]; stor[21:0] <= stor[61:40]; end // holding 48
|
||||
5'hc : begin stor <= {40'h0,stor[103:40]}; end // holding 8
|
||||
5'hd : begin stor[73:8] <= din[65:0]; stor[7:0] <= stor[47:40]; end // holding 34
|
||||
5'he : begin stor[99:34] <= din[65:0]; stor[33:0] <= stor[73:40]; end // holding 60
|
||||
5'hf : begin stor <= {40'h0,stor[103:40]}; end // holding 20
|
||||
5'h10 : begin stor[85:20] <= din[65:0]; stor[19:0] <= stor[59:40]; end // holding 46
|
||||
5'h11 : begin stor <= {40'h0,stor[103:40]}; end // holding 6
|
||||
5'h12 : begin stor[71:6] <= din[65:0]; stor[5:0] <= stor[45:40]; end // holding 32
|
||||
5'h13 : begin stor[97:32] <= din[65:0]; stor[31:0] <= stor[71:40]; end // holding 58
|
||||
5'h14 : begin stor <= {40'h0,stor[103:40]}; end // holding 18
|
||||
5'h15 : begin stor[83:18] <= din[65:0]; stor[17:0] <= stor[57:40]; end // holding 44
|
||||
5'h16 : begin stor <= {40'h0,stor[103:40]}; end // holding 4
|
||||
5'h17 : begin stor[69:4] <= din[65:0]; stor[3:0] <= stor[43:40]; end // holding 30
|
||||
5'h18 : begin stor[95:30] <= din[65:0]; stor[29:0] <= stor[69:40]; end // holding 56
|
||||
5'h19 : begin stor <= {40'h0,stor[103:40]}; end // holding 16
|
||||
5'h1a : begin stor[81:16] <= din[65:0]; stor[15:0] <= stor[55:40]; end // holding 42
|
||||
5'h1b : begin stor <= {40'h0,stor[103:40]}; end // holding 2
|
||||
5'h1c : begin stor[67:2] <= din[65:0]; stor[1:0] <= stor[41:40]; end // holding 28
|
||||
5'h1d : begin stor[93:28] <= din[65:0]; stor[27:0] <= stor[67:40]; end // holding 54
|
||||
5'h1e : begin stor <= {40'h0,stor[103:40]}; end // holding 14
|
||||
5'h1f : begin stor[79:14] <= din[65:0]; stor[13:0] <= stor[53:40]; end // holding 40
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// this is the pattern as corresponding to the states
|
||||
// wire [32:0] in_pattern = 33'b010110101101011010110101101011011;
|
||||
|
||||
// this is adjusted for latency
|
||||
wire [32:0] in_pattern = 33'b101011010110101101011010110101101;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (sclr) din_ack <= 1'b0;
|
||||
else din_ack <= (64'h0 | in_pattern) >> gbstate;
|
||||
end
|
||||
|
||||
wire [32:0] in_pattern2 = 33'b110101101011010110101101011010110;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (sclr) din_pre_ack <= 1'b0;
|
||||
else din_pre_ack <= (64'h0 | in_pattern2) >> gbstate;
|
||||
end
|
||||
|
||||
wire [32:0] in_pattern3 = 33'b011010110101101011010110101101011;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (sclr) din_pre2_ack <= 1'b0;
|
||||
else din_pre2_ack <= (64'h0 | in_pattern3) >> gbstate;
|
||||
end
|
||||
|
||||
|
||||
endmodule
|
@ -0,0 +1,91 @@
|
||||
// Copyright 2010 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module gearbox_66_40_tb ();
|
||||
|
||||
reg clk = 1'b0;
|
||||
reg [65:0] din = 0; // lsbit first
|
||||
reg sclr = 1'b0;
|
||||
wire din_ack;
|
||||
wire [39:0] dout;
|
||||
wire din_pre_ack;
|
||||
wire din_pre2_ack;
|
||||
|
||||
gearbox_66_40 dut_a (.*);
|
||||
|
||||
reg [79:0] history = 0;
|
||||
always @(posedge clk) begin
|
||||
history <= {dout,history[79:40]};
|
||||
end
|
||||
|
||||
wire [39:0] word_locked,slipping;
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for (i=0; i<40; i=i+1) begin
|
||||
|
||||
wire [65:0] recover;
|
||||
wire recover_valid;
|
||||
|
||||
gearbox_40_66 dut_b (
|
||||
.clk,
|
||||
.slip_to_frame(1'b1),
|
||||
.din (history[i+39:i]),
|
||||
.dout (recover),
|
||||
.dout_valid (recover_valid),
|
||||
.slipping(slipping[i]),
|
||||
.word_locked (word_locked[i])
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
reg send_rand = 1'b1;
|
||||
reg [31:0] cntr = 0;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (din_ack) din <= send_rand ? {$random,$random,din[13],din[13]^1'b1} :
|
||||
{30'h0,cntr,2'b00,2'b01};
|
||||
end
|
||||
|
||||
wire all_locked = &word_locked;
|
||||
|
||||
reg fail = 1'b0;
|
||||
initial begin
|
||||
#100 @(posedge all_locked);
|
||||
@(negedge all_locked);
|
||||
$display ("Unexpected loss of lock");
|
||||
fail = 1'b1;
|
||||
end
|
||||
|
||||
initial begin
|
||||
@(posedge all_locked);
|
||||
$display ("locked at time %d",$time);
|
||||
send_rand = 1'b0;
|
||||
#100000 if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
always begin
|
||||
#5 clk <= ~clk;
|
||||
end
|
||||
|
||||
endmodule
|
188
Advanced Synthesis Cookbook/communication/gearbox_67_20.v
Normal file
188
Advanced Synthesis Cookbook/communication/gearbox_67_20.v
Normal file
@ -0,0 +1,188 @@
|
||||
// Copyright 2008 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 09-19-2008
|
||||
// Convert a 67 bit stream to a 20 bit stream
|
||||
// Note : requires a specific din_valid schedule to avoid overflow.
|
||||
//
|
||||
module gearbox_67_20 (
|
||||
input clk,arst,
|
||||
input [66:0] din,
|
||||
input din_valid,
|
||||
output [19:0] dout
|
||||
);
|
||||
|
||||
// worst case : 19 bits surplus, and 67 arriving = 86 bits
|
||||
|
||||
reg [85:0] storage;
|
||||
reg [4:0] wr_ptr /* synthesis preserve */;
|
||||
reg [4:0] next_wr_ptr;
|
||||
reg [85:0] aligned_din;
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
// This is a debug only sanity check
|
||||
//////////////////////////////////////////////////////
|
||||
// synthesis translate off
|
||||
reg [85:0] aligned_din_mask;
|
||||
reg [85:0] storage_mask;
|
||||
|
||||
always @(*) begin
|
||||
case (wr_ptr)
|
||||
5'd19 : aligned_din_mask = {67'h7ffffffffffffffff,19'b0};
|
||||
5'd18 : aligned_din_mask = {1'b0,67'h7ffffffffffffffff,18'b0};
|
||||
5'd17 : aligned_din_mask = {2'b0,67'h7ffffffffffffffff,17'b0};
|
||||
5'd16 : aligned_din_mask = {3'b0,67'h7ffffffffffffffff,16'b0};
|
||||
5'd15 : aligned_din_mask = {4'b0,67'h7ffffffffffffffff,15'b0};
|
||||
5'd14 : aligned_din_mask = {5'b0,67'h7ffffffffffffffff,14'b0};
|
||||
5'd13 : aligned_din_mask = {6'b0,67'h7ffffffffffffffff,13'b0};
|
||||
5'd12 : aligned_din_mask = {7'b0,67'h7ffffffffffffffff,12'b0};
|
||||
5'd11 : aligned_din_mask = {8'b0,67'h7ffffffffffffffff,11'b0};
|
||||
5'd10 : aligned_din_mask = {9'b0,67'h7ffffffffffffffff,10'b0};
|
||||
5'd9 : aligned_din_mask = {10'b0,67'h7ffffffffffffffff,9'b0};
|
||||
5'd8 : aligned_din_mask = {11'b0,67'h7ffffffffffffffff,8'b0};
|
||||
5'd7 : aligned_din_mask = {12'b0,67'h7ffffffffffffffff,7'b0};
|
||||
5'd6 : aligned_din_mask = {13'b0,67'h7ffffffffffffffff,6'b0};
|
||||
5'd5 : aligned_din_mask = {14'b0,67'h7ffffffffffffffff,5'b0};
|
||||
5'd4 : aligned_din_mask = {15'b0,67'h7ffffffffffffffff,4'b0};
|
||||
5'd3 : aligned_din_mask = {16'b0,67'h7ffffffffffffffff,3'b0};
|
||||
5'd2 : aligned_din_mask = {17'b0,67'h7ffffffffffffffff,2'b0};
|
||||
5'd1 : aligned_din_mask = {18'b0,67'h7ffffffffffffffff,1'b0};
|
||||
5'd0 : aligned_din_mask = {19'b0,67'h7ffffffffffffffff};
|
||||
default : aligned_din_mask = 0; // could be X for QOR
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
storage_mask <= 0;
|
||||
end
|
||||
else begin
|
||||
if (din_valid) begin
|
||||
storage_mask <= (storage_mask << 7'd20) | aligned_din_mask;
|
||||
if (|((storage_mask << 7'd20) & aligned_din_mask))
|
||||
$display ("Warning - TX gearbox lost one or more bits");
|
||||
end
|
||||
else
|
||||
storage_mask <= (storage_mask << 7'd20);
|
||||
end
|
||||
end
|
||||
|
||||
wire [19:0] dout_mask;
|
||||
assign dout_mask = storage_mask [85:85-19];
|
||||
|
||||
reg [4:0] flushing;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) flushing <= 5'b11111;
|
||||
else if (|flushing) flushing <= flushing - 1'b1;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
#1 if (din_valid & ~(din[65] ^ din[64]) & (~|flushing)) begin
|
||||
// the data in to the gearbox should have 10 or 01 framing bits
|
||||
// possibly ignoring some pipe flush at reset time
|
||||
$display ("Warning - TX gearbox din is not properly framed");
|
||||
end
|
||||
if (~&dout_mask & (~|flushing)) begin
|
||||
// sim only check for gearbox sending out "missing" bits
|
||||
// possibly ignoring some pipe flush
|
||||
$display ("Warning - some TX gearbox dout bits are invalid");
|
||||
end
|
||||
end
|
||||
|
||||
// synthesis translate on
|
||||
//////////////////////////////////////////////////////
|
||||
// End of sanity check
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
assign dout = storage [85:85-19];
|
||||
|
||||
// semi barrel shifter to align incomming data words
|
||||
always @(*) begin
|
||||
case (wr_ptr)
|
||||
5'd19 : aligned_din = {din,19'b0};
|
||||
5'd18 : aligned_din = {1'b0,din,18'b0};
|
||||
5'd17 : aligned_din = {2'b0,din,17'b0};
|
||||
5'd16 : aligned_din = {3'b0,din,16'b0};
|
||||
5'd15 : aligned_din = {4'b0,din,15'b0};
|
||||
5'd14 : aligned_din = {5'b0,din,14'b0};
|
||||
5'd13 : aligned_din = {6'b0,din,13'b0};
|
||||
5'd12 : aligned_din = {7'b0,din,12'b0};
|
||||
5'd11 : aligned_din = {8'b0,din,11'b0};
|
||||
5'd10 : aligned_din = {9'b0,din,10'b0};
|
||||
5'd9 : aligned_din = {10'b0,din,9'b0};
|
||||
5'd8 : aligned_din = {11'b0,din,8'b0};
|
||||
5'd7 : aligned_din = {12'b0,din,7'b0};
|
||||
5'd6 : aligned_din = {13'b0,din,6'b0};
|
||||
5'd5 : aligned_din = {14'b0,din,5'b0};
|
||||
5'd4 : aligned_din = {15'b0,din,4'b0};
|
||||
5'd3 : aligned_din = {16'b0,din,3'b0};
|
||||
5'd2 : aligned_din = {17'b0,din,2'b0};
|
||||
5'd1 : aligned_din = {18'b0,din,1'b0};
|
||||
5'd0 : aligned_din = {19'b0,din};
|
||||
default : aligned_din = 0; // could be X for QOR
|
||||
endcase
|
||||
end
|
||||
|
||||
// figure out where the next word will need to be loaded
|
||||
always @(*) begin
|
||||
case (wr_ptr)
|
||||
5'd19 : next_wr_ptr = 5'd12; // residue 0 + 67 new = 7 leftover
|
||||
5'd18 : next_wr_ptr = 5'd11; // residue 1 + 67 new = 8 leftover
|
||||
5'd17 : next_wr_ptr = 5'd10; // residue 2 + 67 new = 9 leftover
|
||||
5'd16 : next_wr_ptr = 5'd9; // residue 3 + 67 new = 10 leftover
|
||||
5'd15 : next_wr_ptr = 5'd8; // residue 4 + 67 new = 11 leftover
|
||||
5'd14 : next_wr_ptr = 5'd7; // residue 5 + 67 new = 12 leftover
|
||||
5'd13 : next_wr_ptr = 5'd6; // residue 6 + 67 new = 13 leftover
|
||||
5'd12 : next_wr_ptr = 5'd5; // residue 7 + 67 new = 14 leftover
|
||||
5'd11 : next_wr_ptr = 5'd4; // residue 8 + 67 new = 15 leftover
|
||||
5'd10 : next_wr_ptr = 5'd3; // residue 9 + 67 new = 16 leftover
|
||||
5'd9 : next_wr_ptr = 5'd2; // residue 10 + 67 new = 17 leftover
|
||||
5'd8 : next_wr_ptr = 5'd1; // residue 11 + 67 new = 18 leftover
|
||||
5'd7 : next_wr_ptr = 5'd0; // residue 12 + 67 new = 19 leftover
|
||||
5'd6 : next_wr_ptr = 5'd19; // residue 13 + 67 new = 0 leftover
|
||||
5'd5 : next_wr_ptr = 5'd18; // residue 14 + 67 new = 1 leftover
|
||||
5'd4 : next_wr_ptr = 5'd17; // residue 15 + 67 new = 2 leftover
|
||||
5'd3 : next_wr_ptr = 5'd16; // residue 16 + 67 new = 3 leftover
|
||||
5'd2 : next_wr_ptr = 5'd15; // residue 17 + 67 new = 4 leftover
|
||||
5'd1 : next_wr_ptr = 5'd14; // residue 18 + 67 new = 5 leftover
|
||||
5'd0 : next_wr_ptr = 5'd13; // residue 19 + 67 new = 6 leftover
|
||||
default : next_wr_ptr = 5'd0;
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
wr_ptr <= 7'd19;
|
||||
storage <= 0;
|
||||
end
|
||||
else begin
|
||||
if (din_valid) begin
|
||||
storage <= (storage << 7'd20) | aligned_din;
|
||||
wr_ptr <= next_wr_ptr;
|
||||
end
|
||||
else begin
|
||||
storage <= (storage << 7'd20);
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
126
Advanced Synthesis Cookbook/communication/gearbox_67_20_tb.sv
Normal file
126
Advanced Synthesis Cookbook/communication/gearbox_67_20_tb.sv
Normal file
@ -0,0 +1,126 @@
|
||||
// Copyright 2009 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 09-19-2008
|
||||
|
||||
module gearbox_67_20_tb ();
|
||||
|
||||
reg clk,arst,late_arst;
|
||||
reg [66:0] din;
|
||||
reg din_valid;
|
||||
wire [19:0] dout;
|
||||
wire [66:0] recovered;
|
||||
wire recovered_valid;
|
||||
|
||||
gearbox_67_20 dut (
|
||||
.*
|
||||
);
|
||||
|
||||
gearbox_20_67 dut_b (
|
||||
.clk,
|
||||
.arst(late_arst),
|
||||
.din(dout),
|
||||
.slip_to_frame(1'b1),
|
||||
.dout(recovered),
|
||||
.dout_valid(recovered_valid)
|
||||
);
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
#1 arst = 1'b1; late_arst = 1'b1;
|
||||
@(negedge clk) arst = 1'b0;
|
||||
@(negedge clk) late_arst = 1'b0;
|
||||
|
||||
end
|
||||
|
||||
always begin
|
||||
#5 clk = ~clk;
|
||||
end
|
||||
|
||||
reg [20*67-1:0] data_stream = {
|
||||
3'b010, 64'h1234167812345670,
|
||||
3'b010, 64'h2bcd2f12abcdef12,
|
||||
3'b010, 64'h3234367812345679,
|
||||
3'b010, 64'h4bcd4f12abcdef13,
|
||||
3'b010, 64'h5234567812345670,
|
||||
3'b010, 64'h6bcd6f12abcdef11,
|
||||
3'b010, 64'h7234767812345674,
|
||||
3'b010, 64'h8bcd8f12abcdef13,
|
||||
3'b010, 64'h9234967812345670,
|
||||
3'b010, 64'habcdaf12abcdef11,
|
||||
3'b010, 64'hb234b67812345679,
|
||||
3'b010, 64'hcbcdcf12abcdef13,
|
||||
3'b010, 64'hd234d67812345670,
|
||||
3'b010, 64'hebcdef12abcdef11,
|
||||
3'b010, 64'hf234f67812345679,
|
||||
3'b010, 64'h0bcd0f12abcdef13,
|
||||
3'b010, 64'h1234167812345670,
|
||||
3'b010, 64'h2bcd2f12abcdef11,
|
||||
3'b010, 64'h3234367812345679,
|
||||
3'b010, 64'h4234467812345679
|
||||
};
|
||||
|
||||
reg [20*67-1:0] data_stream_readback;
|
||||
|
||||
reg [66:0] schedule = 67'b1001001000100100100010010010001001001000100100100010010010001001000;
|
||||
|
||||
//////////////////////////////
|
||||
// Loop the sample data in
|
||||
//////////////////////////////
|
||||
integer n = 0;
|
||||
always begin
|
||||
#2 if (!arst) begin
|
||||
din = 0;
|
||||
for (n=0;n<67;n=n+1) begin
|
||||
din = data_stream[66:0];
|
||||
din_valid = schedule[66-n];
|
||||
@(negedge clk);
|
||||
if (din_valid) data_stream =
|
||||
{data_stream[66:0],data_stream[20*67-1:67]};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//////////////////////////////
|
||||
// verify recovery
|
||||
//////////////////////////////
|
||||
reg fail = 0;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) data_stream_readback = data_stream;
|
||||
else begin
|
||||
#1 if (recovered_valid) begin
|
||||
if (recovered !== data_stream_readback[66:0]) begin
|
||||
$display ("Mismatch at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
data_stream_readback =
|
||||
{data_stream_readback[66:0],data_stream_readback[20*67-1:67]};
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
initial begin
|
||||
#1000000 if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
endmodule
|
223
Advanced Synthesis Cookbook/communication/gearbox_67_40.v
Normal file
223
Advanced Synthesis Cookbook/communication/gearbox_67_40.v
Normal file
@ -0,0 +1,223 @@
|
||||
// Copyright 2009 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 03-28-2008
|
||||
|
||||
module gearbox_67_40 (
|
||||
input clk,arst,
|
||||
input [66:0] din,
|
||||
output din_ready,
|
||||
output reg [39:0] dout
|
||||
);
|
||||
|
||||
// input reg
|
||||
reg [66:0] din_r;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) din_r <= 0;
|
||||
else if (din_ready) din_r <= din;
|
||||
end
|
||||
|
||||
// where are we in the schedule?
|
||||
reg [6:0] phase;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) phase <= 0;
|
||||
else begin
|
||||
if (phase == 66) phase <= 0;
|
||||
else phase <= phase + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// shift the input word left to enter storage at the right place
|
||||
reg [96:0] positioned_data;
|
||||
reg [3:0] dshift /* synthesis preserve */;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) positioned_data <= 0;
|
||||
else begin
|
||||
case (dshift)
|
||||
4'h0 : positioned_data <= din_r << 0;
|
||||
4'h1 : positioned_data <= din_r << 1;
|
||||
4'h2 : positioned_data <= din_r << 2;
|
||||
4'h3 : positioned_data <= din_r << 3;
|
||||
4'h4 : positioned_data <= din_r << 4;
|
||||
4'h5 : positioned_data <= din_r << 13;
|
||||
4'h6 : positioned_data <= din_r << 14;
|
||||
4'h7 : positioned_data <= din_r << 15;
|
||||
4'h8 : positioned_data <= din_r << 16;
|
||||
4'h9 : positioned_data <= din_r << 17;
|
||||
4'ha : positioned_data <= din_r << 26;
|
||||
4'hb : positioned_data <= din_r << 27;
|
||||
4'hc : positioned_data <= din_r << 28;
|
||||
4'hd : positioned_data <= din_r << 29;
|
||||
4'he : positioned_data <= din_r << 30;
|
||||
4'hf : positioned_data <= 0; // no din on this tick
|
||||
endcase
|
||||
end
|
||||
end
|
||||
assign din_ready = ~&dshift;
|
||||
|
||||
// on every tick shift storage left by one of a couple of distance
|
||||
// choices, and merge in the positioned data
|
||||
reg [105:0] storage;
|
||||
reg sshift /* synthesis preserve */;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) storage <= 0;
|
||||
else begin
|
||||
case (sshift)
|
||||
1'b0 : storage <= (storage << 40) | positioned_data;
|
||||
1'b1 : storage <= (storage << 45) | positioned_data;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// extract an output word from one of a couple of choices
|
||||
reg [1:0] epoint /* synthesis preserve */;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
dout <= 0;
|
||||
end
|
||||
else begin
|
||||
case (epoint)
|
||||
2'b00: dout <= storage [95:95-39];
|
||||
2'b01: dout <= storage [100:100-39];
|
||||
2'b10: dout <= storage [105:105-39];
|
||||
|
||||
// this one is don't care
|
||||
2'b11: dout <= storage [105:105-39];
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// The schedule - expected to map into one 6LUT per output bit
|
||||
// if it goes to ROM be sure to suppress
|
||||
reg [3:0] ds /* synthesis preserve */;
|
||||
reg [3:0] dsalt;
|
||||
reg ss /* synthesis preserve */;
|
||||
reg [1:0] ep /* synthesis preserve */;
|
||||
reg ssalt;
|
||||
reg [1:0] epalt;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
ds <= 0;
|
||||
dsalt <= 0;
|
||||
ss <= 0;
|
||||
ssalt <= 0;
|
||||
ep <= 0;
|
||||
epalt <= 0;
|
||||
end
|
||||
else begin
|
||||
case (phase[5:0])
|
||||
6'h00 : begin ds <= 4'h2; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h01 : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h0; end
|
||||
6'h02 : begin ds <= 4'h7; ss <= 1'h0; ep <= 2'h0; end
|
||||
6'h03 : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h0; end
|
||||
6'h04 : begin ds <= 4'hc; ss <= 1'h0; ep <= 2'h0; end
|
||||
6'h05 : begin ds <= 4'h1; ss <= 1'h0; ep <= 2'h0; end
|
||||
6'h06 : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h0; end
|
||||
6'h07 : begin ds <= 4'h6; ss <= 1'h0; ep <= 2'h0; end
|
||||
6'h08 : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h0; end
|
||||
6'h09 : begin ds <= 4'hb; ss <= 1'h0; ep <= 2'h0; end
|
||||
6'h0a : begin ds <= 4'h0; ss <= 1'h0; ep <= 2'h0; end
|
||||
6'h0b : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h0; end
|
||||
6'h0c : begin ds <= 4'h5; ss <= 1'h0; ep <= 2'h0; end
|
||||
6'h0d : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h0; end
|
||||
6'h0e : begin ds <= 4'ha; ss <= 1'h0; ep <= 2'h0; end
|
||||
6'h0f : begin ds <= 4'h4; ss <= 1'h0; ep <= 2'h0; end
|
||||
6'h10 : begin ds <= 4'hf; ss <= 1'h1; ep <= 2'h0; end
|
||||
6'h11 : begin ds <= 4'h9; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h12 : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h13 : begin ds <= 4'he; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h14 : begin ds <= 4'h3; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h15 : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h16 : begin ds <= 4'h8; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h17 : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h18 : begin ds <= 4'hd; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h19 : begin ds <= 4'h2; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h1a : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h1b : begin ds <= 4'h7; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h1c : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h1d : begin ds <= 4'hc; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h1e : begin ds <= 4'h1; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h1f : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h20 : begin ds <= 4'h6; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h21 : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h22 : begin ds <= 4'hb; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h23 : begin ds <= 4'h0; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h24 : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h25 : begin ds <= 4'h5; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h26 : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h27 : begin ds <= 4'ha; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h28 : begin ds <= 4'h4; ss <= 1'h0; ep <= 2'h1; end
|
||||
6'h29 : begin ds <= 4'hf; ss <= 1'h1; ep <= 2'h1; end
|
||||
6'h2a : begin ds <= 4'h9; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h2b : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h2c : begin ds <= 4'he; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h2d : begin ds <= 4'h3; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h2e : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h2f : begin ds <= 4'h8; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h30 : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h31 : begin ds <= 4'hd; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h32 : begin ds <= 4'h2; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h33 : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h34 : begin ds <= 4'h7; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h35 : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h36 : begin ds <= 4'hc; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h37 : begin ds <= 4'h1; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h38 : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h39 : begin ds <= 4'h6; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h3a : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h3b : begin ds <= 4'hb; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h3c : begin ds <= 4'h0; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h3d : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h3e : begin ds <= 4'h5; ss <= 1'h0; ep <= 2'h2; end
|
||||
6'h3f : begin ds <= 4'hf; ss <= 1'h0; ep <= 2'h2; end
|
||||
endcase
|
||||
|
||||
case (phase[1:0])
|
||||
2'h0 : begin dsalt <= 4'ha; ssalt <= 1'h0; epalt <= 2'h2; end
|
||||
2'h1 : begin dsalt <= 4'hf; ssalt <= 1'h0; epalt <= 2'h2; end
|
||||
2'h2 : begin dsalt <= 4'hd; ssalt <= 1'h0; epalt <= 2'h2; end
|
||||
|
||||
// this one is actually don't care
|
||||
2'h3 : begin dsalt <= 4'hd; ssalt <= 1'h0; epalt <= 2'h2; end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// phase 64,5,6 use the alternate schedule
|
||||
reg use_alt;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
sshift <= 0;
|
||||
dshift <= 0;
|
||||
epoint <= 0;
|
||||
use_alt <= 0;
|
||||
end
|
||||
else begin
|
||||
sshift <= use_alt ? ssalt : ss;
|
||||
dshift <= use_alt ? dsalt : ds;
|
||||
epoint <= use_alt ? epalt : ep;
|
||||
use_alt <= phase[6];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
357
Advanced Synthesis Cookbook/communication/parallax_gps.v
Normal file
357
Advanced Synthesis Cookbook/communication/parallax_gps.v
Normal file
@ -0,0 +1,357 @@
|
||||
// Copyright 2008 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 04-30-2008
|
||||
|
||||
module parallax_gps (
|
||||
input clk,rst,
|
||||
input s_din,
|
||||
output s_dout,
|
||||
output s_oe,
|
||||
|
||||
output reg [7:0] hw_version,
|
||||
output reg info_valid,
|
||||
output reg [3:0] sats,
|
||||
output reg [23:0] gmt_time, // H, M, S
|
||||
output reg [23:0] gmt_date, // M, D, Y
|
||||
output reg [39:0] lattitude, // Deg, Min, Min/FFFF, 0=N,1=S
|
||||
output reg [39:0] longitude, // Deg, Min, Min/FFFF, 0=E,1=W
|
||||
output reg [15:0] altitude, // 1/10 M
|
||||
output reg [15:0] speed, // 1/10 knots
|
||||
output reg [15:0] heading, // 1/10 degrees
|
||||
|
||||
// diagnostic information
|
||||
output [3:0] current_query,
|
||||
output [3:0] timeouts
|
||||
);
|
||||
|
||||
/////////////////////////////
|
||||
// SIO regs
|
||||
/////////////////////////////
|
||||
reg din_r /* synthesis altera_attribute = "FAST_INPUT_REGISTER=ON" */;
|
||||
reg dout_r /* synthesis altera_attribute = "FAST_OUTPUT_REGISTER=ON" */;
|
||||
reg oe_r /* synthesis altera_attribute = "FAST_OUTPUT_ENABLE_REGISTER=ON" */;
|
||||
|
||||
wire dout_w;
|
||||
reg oe_w;
|
||||
assign s_dout = dout_r;
|
||||
assign s_oe = oe_r;
|
||||
|
||||
always @(posedge clk) begin
|
||||
din_r <= s_din;
|
||||
dout_r <= dout_w;
|
||||
oe_r <= oe_w;
|
||||
end
|
||||
|
||||
/////////////////////////////
|
||||
// 4800 N81 Uart
|
||||
/////////////////////////////
|
||||
|
||||
reg [7:0] tx_data;
|
||||
reg tx_data_valid;
|
||||
wire tx_data_ack,txd;
|
||||
wire [7:0] rx_data;
|
||||
wire rx_data_fresh;
|
||||
reg forced_idle;
|
||||
|
||||
assign dout_w = forced_idle | txd;
|
||||
|
||||
uart ur (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.tx_data(tx_data),
|
||||
.tx_data_valid(tx_data_valid),
|
||||
.tx_data_ack(tx_data_ack),
|
||||
.txd(txd),
|
||||
.rx_data(rx_data),
|
||||
.rx_data_fresh(rx_data_fresh),
|
||||
.rxd(din_r)
|
||||
);
|
||||
defparam ur .BAUD = 4800;
|
||||
defparam ur .CLK_HZ = 50_000_000;
|
||||
|
||||
/////////////////////////////
|
||||
// Insert some idle bits
|
||||
// to deal with RX and TX handoff
|
||||
// on the same line.
|
||||
/////////////////////////////
|
||||
reg [13:0] idle_timer;
|
||||
reg idle_max;
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
idle_timer <= 0;
|
||||
idle_max <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
if (forced_idle) idle_timer <= idle_timer + 1'b1;
|
||||
idle_max <= &idle_timer;
|
||||
end
|
||||
end
|
||||
|
||||
/////////////////////////////
|
||||
// capture read bytes
|
||||
/////////////////////////////
|
||||
reg [8*5-1:0] rx_history;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) rx_history <= 0;
|
||||
else if (rx_data_fresh) begin
|
||||
rx_history <= (rx_history << 4'h8) | rx_data;
|
||||
end
|
||||
end
|
||||
|
||||
/////////////////////////////
|
||||
// commands
|
||||
/////////////////////////////
|
||||
reg [3:0] cmd_reg;
|
||||
reg inc_cmd;
|
||||
always @(posedge clk) begin
|
||||
if (rst) cmd_reg <= 0;
|
||||
else begin
|
||||
if (inc_cmd) begin
|
||||
if (cmd_reg == 4'h9) cmd_reg <= 0;
|
||||
else cmd_reg <= cmd_reg + 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
/////////////////////////////
|
||||
// reply timer
|
||||
// wait until either
|
||||
// the transmitter finishes 512 dummy chars
|
||||
// the receiver gets the appropriate number of bytes
|
||||
/////////////////////////////
|
||||
reg [9:0] reply_cntr;
|
||||
reg clr_reply_cntr, reply_cntr_max, prompt_complete;
|
||||
reg [2:0] expected_bytes;
|
||||
reg [3:0] timeout_counter;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) timeout_counter <= 0;
|
||||
if (rst | clr_reply_cntr) begin
|
||||
reply_cntr <= 0;
|
||||
reply_cntr_max <= 0;
|
||||
if ((cmd_reg == 0) ||
|
||||
(cmd_reg == 1) ||
|
||||
(cmd_reg == 2)) expected_bytes <= 3'd1;
|
||||
else if ((cmd_reg == 3) ||
|
||||
(cmd_reg == 4)) expected_bytes <= 3'd3;
|
||||
else if ((cmd_reg == 5) ||
|
||||
(cmd_reg == 6)) expected_bytes <= 3'd5;
|
||||
else expected_bytes <= 3'd2;
|
||||
prompt_complete <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
// make sure you're past the !GPSn prompt string
|
||||
// before counting bytes
|
||||
if (rx_history[23:8] == "PS") prompt_complete <= 1'b1;
|
||||
|
||||
if (tx_data_ack) reply_cntr <= reply_cntr + 1'b1;
|
||||
if (rx_data_fresh & prompt_complete) expected_bytes <= expected_bytes - 1'b1;
|
||||
|
||||
reply_cntr_max <= 1'b0;
|
||||
if (&reply_cntr) begin
|
||||
reply_cntr_max <= 1'b1;
|
||||
if (!reply_cntr_max) timeout_counter <= timeout_counter + 1'b1;
|
||||
end
|
||||
if (~|expected_bytes) begin
|
||||
reply_cntr_max <= 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
/////////////////////////////
|
||||
// Data regs
|
||||
/////////////////////////////
|
||||
reg grab_data;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
hw_version <= 0;
|
||||
info_valid <= 0;
|
||||
sats <= 0;
|
||||
gmt_time <= 0;
|
||||
gmt_date <= 0;
|
||||
lattitude <= 0;
|
||||
longitude <= 0;
|
||||
altitude <= 0;
|
||||
speed <= 0;
|
||||
heading <= 0;
|
||||
end
|
||||
else if (grab_data) begin
|
||||
if (cmd_reg == 4'h0) hw_version <= rx_history [7:0];
|
||||
if (cmd_reg == 4'h1) info_valid <= rx_history [0];
|
||||
if (cmd_reg == 4'h2) sats <= rx_history [3:0];
|
||||
if (cmd_reg == 4'h3) gmt_time <= rx_history [23:0];
|
||||
if (cmd_reg == 4'h4) gmt_date <= rx_history [23:0];
|
||||
if (cmd_reg == 4'h5) lattitude <= rx_history [39:0];
|
||||
if (cmd_reg == 4'h6) longitude <= rx_history [39:0];
|
||||
if (cmd_reg == 4'h7) altitude <= rx_history [15:0];
|
||||
if (cmd_reg == 4'h8) speed <= rx_history [15:0];
|
||||
if (cmd_reg == 4'h9) heading <= rx_history [15:0];
|
||||
end
|
||||
end
|
||||
|
||||
/////////////////////////////
|
||||
// Cycle through data requests
|
||||
/////////////////////////////
|
||||
reg [3:0] state /* synthesis preserve */;
|
||||
reg [3:0] next_state;
|
||||
|
||||
parameter
|
||||
ST_INIT = 0,
|
||||
ST_PRESEND = 1,
|
||||
ST_PRESEND1 = 2,
|
||||
ST_PRESEND2 = 3,
|
||||
ST_PRESEND3 = 4,
|
||||
ST_SEND = 5,
|
||||
ST_SEND1 = 6,
|
||||
ST_SEND2 = 7,
|
||||
ST_SEND3 = 8,
|
||||
ST_SEND4 = 9,
|
||||
ST_TX_PENDING = 10,
|
||||
ST_PRELISTEN = 11,
|
||||
ST_LISTEN = 12,
|
||||
ST_REPORT = 13,
|
||||
ST_NEXT_CMD = 14;
|
||||
|
||||
always @(*) begin
|
||||
next_state = state;
|
||||
tx_data = 0;
|
||||
tx_data_valid = 0;
|
||||
oe_w = 1'b0;
|
||||
clr_reply_cntr = 1'b0;
|
||||
inc_cmd = 1'b0;
|
||||
grab_data = 1'b0;
|
||||
forced_idle = 1'b0;
|
||||
|
||||
case (state)
|
||||
ST_INIT : begin
|
||||
next_state = ST_PRESEND;
|
||||
end
|
||||
ST_PRESEND : begin
|
||||
// force the line to idle for 1 char
|
||||
oe_w = 1'b1;
|
||||
forced_idle = 1'b1;
|
||||
tx_data = 0;
|
||||
tx_data_valid = 1'b1;
|
||||
if (tx_data_ack) next_state = ST_PRESEND1;
|
||||
end
|
||||
ST_PRESEND1 : begin
|
||||
// force the line to idle for 1 char
|
||||
oe_w = 1'b1;
|
||||
forced_idle = 1'b1;
|
||||
tx_data = 0;
|
||||
tx_data_valid = 1'b1;
|
||||
if (tx_data_ack) next_state = ST_PRESEND2;
|
||||
end
|
||||
ST_PRESEND2 : begin
|
||||
// force the line to idle for 1 char
|
||||
oe_w = 1'b1;
|
||||
forced_idle = 1'b1;
|
||||
tx_data = 0;
|
||||
tx_data_valid = 1'b1;
|
||||
if (tx_data_ack) next_state = ST_PRESEND3;
|
||||
end
|
||||
ST_PRESEND3 : begin
|
||||
// force the line to idle for 1 char
|
||||
oe_w = 1'b1;
|
||||
forced_idle = 1'b1;
|
||||
tx_data = 0;
|
||||
tx_data_valid = 1'b1;
|
||||
if (tx_data_ack) next_state = ST_SEND;
|
||||
end
|
||||
ST_SEND : begin
|
||||
oe_w = 1'b1;
|
||||
tx_data = "!";
|
||||
tx_data_valid = 1'b1;
|
||||
if (tx_data_ack) next_state = ST_SEND1;
|
||||
end
|
||||
ST_SEND1 : begin
|
||||
oe_w = 1'b1;
|
||||
tx_data = "G";
|
||||
tx_data_valid = 1'b1;
|
||||
if (tx_data_ack) next_state = ST_SEND2;
|
||||
end
|
||||
ST_SEND2 : begin
|
||||
oe_w = 1'b1;
|
||||
tx_data = "P";
|
||||
tx_data_valid = 1'b1;
|
||||
if (tx_data_ack) next_state = ST_SEND3;
|
||||
end
|
||||
ST_SEND3 : begin
|
||||
oe_w = 1'b1;
|
||||
tx_data = "S";
|
||||
tx_data_valid = 1'b1;
|
||||
if (tx_data_ack) next_state = ST_SEND4;
|
||||
end
|
||||
ST_SEND4 : begin
|
||||
oe_w = 1'b1;
|
||||
tx_data = {4'h0,cmd_reg};
|
||||
tx_data_valid = 1'b1;
|
||||
if (tx_data_ack) next_state = ST_TX_PENDING;
|
||||
end
|
||||
ST_TX_PENDING : begin
|
||||
// wait until the last command
|
||||
// byte is done sending
|
||||
oe_w = 1'b1;
|
||||
tx_data = 0;
|
||||
tx_data_valid = 1'b1;
|
||||
if (tx_data_ack) next_state = ST_PRELISTEN;
|
||||
end
|
||||
ST_PRELISTEN : begin
|
||||
// force the line to idle for 1 char
|
||||
clr_reply_cntr = 1'b1;
|
||||
oe_w = 1'b1;
|
||||
forced_idle = 1'b1;
|
||||
tx_data = 0;
|
||||
tx_data_valid = 1'b1;
|
||||
if (tx_data_ack) next_state = ST_LISTEN;
|
||||
end
|
||||
ST_LISTEN : begin
|
||||
// wait until reply complete or timeout
|
||||
forced_idle = 1'b1;
|
||||
tx_data = 0;
|
||||
tx_data_valid = 1'b1;
|
||||
if (reply_cntr_max) next_state = ST_REPORT;
|
||||
end
|
||||
ST_REPORT : begin
|
||||
grab_data = 1'b1;
|
||||
next_state = ST_NEXT_CMD;
|
||||
end
|
||||
ST_NEXT_CMD : begin
|
||||
inc_cmd = 1'b1;
|
||||
next_state = ST_PRESEND;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) state <= ST_INIT;
|
||||
else state <= next_state;
|
||||
end
|
||||
|
||||
// diagnostic info
|
||||
assign current_query = cmd_reg;
|
||||
assign timeouts = timeout_counter;
|
||||
|
||||
endmodule
|
60
Advanced Synthesis Cookbook/communication/scrambler.v
Normal file
60
Advanced Synthesis Cookbook/communication/scrambler.v
Normal file
@ -0,0 +1,60 @@
|
||||
// Copyright 2011 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`timescale 1 ps / 1 ps
|
||||
|
||||
// baeckler - 12-17-2008
|
||||
// Unrolled scrambler LFSR
|
||||
|
||||
module scrambler # (
|
||||
parameter WIDTH = 512
|
||||
)(
|
||||
input clk,arst,ena,
|
||||
input [WIDTH-1:0] din, // bit 0 is to be sent first
|
||||
output reg [WIDTH-1:0] dout
|
||||
);
|
||||
localparam SCRAM_INIT = 58'h3ff_ffff_ffff_ffff;
|
||||
|
||||
reg [57:0] scram_state = SCRAM_INIT;
|
||||
wire [WIDTH+58-1:0] history;
|
||||
assign history [57:0] = scram_state;
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
for (i=58; i<WIDTH+58; i=i+1) begin : lp
|
||||
assign history[i] = history[i-58] ^ history[i-39] ^ din[i-58];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
dout <= 0;
|
||||
scram_state <= SCRAM_INIT;
|
||||
end
|
||||
else if (ena) begin
|
||||
dout <= history[WIDTH+58-1:58];
|
||||
scram_state <= history[WIDTH+58-1:WIDTH];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
133
Advanced Synthesis Cookbook/communication/scrambler_tb.sv
Normal file
133
Advanced Synthesis Cookbook/communication/scrambler_tb.sv
Normal file
@ -0,0 +1,133 @@
|
||||
// Copyright 2010 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`timescale 1 ps / 1 ps
|
||||
// baeckler - 12-17-2008
|
||||
|
||||
module scrambler_tb ();
|
||||
|
||||
parameter WIDTH = 256;
|
||||
|
||||
reg clk = 0, arst = 0;
|
||||
|
||||
// sample data
|
||||
reg [WIDTH-1:0] data_in = 0;
|
||||
reg [15:0] cntr = 0;
|
||||
integer k = 0;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
data_in <= 0;
|
||||
cntr <= 0;
|
||||
end
|
||||
else begin
|
||||
#1
|
||||
for (k=0; k<(WIDTH >> 4); k=k+1) begin : stim
|
||||
data_in = (data_in << 16) | cntr;
|
||||
cntr = cntr + 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
reg [WIDTH-1:0] last_data_in, last2_data_in;
|
||||
reg [3:0] flushing;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
last_data_in <= 0;
|
||||
last2_data_in <= 0;
|
||||
flushing <= 4'b1111;
|
||||
end
|
||||
else begin
|
||||
last_data_in <= data_in;
|
||||
last2_data_in <= last_data_in;
|
||||
flushing <= {flushing[2:0],1'b0};
|
||||
end
|
||||
end
|
||||
|
||||
// 1 bit LFSR model
|
||||
integer n;
|
||||
reg fbk;
|
||||
reg [57:0] lfsr;
|
||||
reg [WIDTH-1:0] lfsr_out;
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
lfsr_out = 0;
|
||||
lfsr = 58'h3ff_ffff_ffff_ffff;
|
||||
end
|
||||
else begin
|
||||
for (n=0; n<WIDTH; n=n+1) begin : lf
|
||||
fbk = (lfsr[57] ^ lfsr[38] ^ data_in[n]);
|
||||
lfsr = {lfsr[56:0],fbk};
|
||||
lfsr_out[n] = fbk;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// XOR network scrambler
|
||||
wire [WIDTH-1:0] scram_out;
|
||||
scrambler # (.WIDTH(WIDTH)) duts
|
||||
(
|
||||
.clk,
|
||||
.arst,
|
||||
.ena(1'b1),
|
||||
.din(data_in), // bit 0 is to be sent first
|
||||
.dout(scram_out)
|
||||
);
|
||||
|
||||
// XOR network descrambler
|
||||
wire [WIDTH-1:0] recover_out;
|
||||
descrambler # (.WIDTH(WIDTH)) dutd
|
||||
(
|
||||
.clk,
|
||||
.arst,
|
||||
.ena(1'b1),
|
||||
.din(scram_out), // bit 0 is to be sent first
|
||||
.dout(recover_out)
|
||||
);
|
||||
|
||||
reg fail = 0;
|
||||
always @(posedge clk) begin
|
||||
#1 if (lfsr_out !== scram_out) begin
|
||||
$display ("Scrambler does not match 1 bit model at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
if (recover_out !== last2_data_in && ~|flushing) begin
|
||||
$display ("Recovered data is not as expected at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
end
|
||||
|
||||
// clock driver
|
||||
initial begin
|
||||
#1 arst = 1'b1;
|
||||
@(negedge clk) arst = 1'b0;
|
||||
end
|
||||
|
||||
always begin
|
||||
#5 clk = ~clk;
|
||||
end
|
||||
|
||||
initial begin
|
||||
#100000 if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
endmodule
|
74
Advanced Synthesis Cookbook/communication/two_to_one.v
Normal file
74
Advanced Synthesis Cookbook/communication/two_to_one.v
Normal file
@ -0,0 +1,74 @@
|
||||
// Copyright 2009 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 01-22-2009
|
||||
// accept 2 words, output in single words
|
||||
// send the less significant end through first
|
||||
|
||||
module two_to_one #(
|
||||
parameter WORD_LEN = 33
|
||||
)
|
||||
(
|
||||
input clk,arst,
|
||||
|
||||
input [2*WORD_LEN-1:0] din,
|
||||
input din_valid,
|
||||
output din_ready,
|
||||
|
||||
output [WORD_LEN-1:0] dout,
|
||||
input dout_ready,
|
||||
output dout_valid
|
||||
);
|
||||
|
||||
reg [1:0] holding; // holding 0..2 words
|
||||
reg [2*WORD_LEN-1:0] storage;
|
||||
|
||||
assign din_ready =
|
||||
(holding == 2'b0) ||
|
||||
((holding == 2'b1) && dout_ready);
|
||||
assign dout_valid = (|holding);
|
||||
assign dout = storage[WORD_LEN-1:0];
|
||||
|
||||
always @(posedge clk or posedge arst) begin
|
||||
if (arst) begin
|
||||
storage <= 0;
|
||||
holding <= 0;
|
||||
end
|
||||
else begin
|
||||
if (din_ready & din_valid) begin
|
||||
// if we are reloading it goes to 2 blocks available
|
||||
storage <= din;
|
||||
holding <= 2'b10;
|
||||
end
|
||||
else begin
|
||||
// not reloading
|
||||
// if the output side is ready lose one block
|
||||
if (dout_valid & dout_ready) begin
|
||||
holding <= holding - 1'b1;
|
||||
storage <= {{(WORD_LEN){1'b0}},
|
||||
storage[2*WORD_LEN-1:WORD_LEN]};
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
225
Advanced Synthesis Cookbook/communication/uart.v
Normal file
225
Advanced Synthesis Cookbook/communication/uart.v
Normal file
@ -0,0 +1,225 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 02-16-2007
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
module uart_tx (clk,rst,tx_data,tx_data_valid,tx_data_ack,txd);
|
||||
|
||||
output txd;
|
||||
input clk, rst;
|
||||
input [7:0] tx_data;
|
||||
input tx_data_valid;
|
||||
output tx_data_ack;
|
||||
|
||||
parameter BAUD_DIVISOR = 868;
|
||||
|
||||
reg [15:0] sample_cntr;
|
||||
reg [10:0] tx_shift;
|
||||
reg sample_now;
|
||||
reg tx_data_ack;
|
||||
|
||||
assign txd = tx_shift[0];
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
sample_cntr <= 0;
|
||||
sample_now <= 1'b0;
|
||||
end
|
||||
else if (sample_cntr == (BAUD_DIVISOR-1)) begin
|
||||
sample_cntr <= 0;
|
||||
sample_now <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
sample_now <= 1'b0;
|
||||
sample_cntr <= sample_cntr + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
reg ready;
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
tx_shift <= {11'b00000000001};
|
||||
ready <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
if (!ready & sample_now) begin
|
||||
tx_shift <= {1'b0,tx_shift[10:1]};
|
||||
tx_data_ack <= 1'b0;
|
||||
ready <= ~|tx_shift[10:1];
|
||||
end
|
||||
else if (ready & tx_data_valid) begin
|
||||
tx_shift[10:1] <= {1'b1,tx_data,1'b0};
|
||||
tx_data_ack <= 1'b1;
|
||||
ready <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
tx_data_ack <= 1'b0;
|
||||
ready <= ~|tx_shift[10:1];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
module uart_rx (clk,rst,rx_data,rx_data_fresh,rxd);
|
||||
|
||||
input clk, rst, rxd;
|
||||
output [7:0] rx_data;
|
||||
output rx_data_fresh;
|
||||
|
||||
parameter BAUD_DIVISOR = 868;
|
||||
|
||||
reg [15:0] sample_cntr;
|
||||
reg [7:0] rx_shift;
|
||||
reg sample_now;
|
||||
reg [7:0] rx_data;
|
||||
reg rx_data_fresh;
|
||||
|
||||
reg last_rxd;
|
||||
always @(posedge clk) begin
|
||||
last_rxd <= rxd;
|
||||
end
|
||||
wire slew = rxd ^ last_rxd;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
sample_cntr <= 0;
|
||||
sample_now <= 1'b0;
|
||||
end
|
||||
else if (sample_cntr == (BAUD_DIVISOR-1) || slew) begin
|
||||
sample_cntr <= 0;
|
||||
end
|
||||
else if (sample_cntr == (BAUD_DIVISOR/2)) begin
|
||||
sample_now <= 1'b1;
|
||||
sample_cntr <= sample_cntr + 1'b1;
|
||||
end
|
||||
else begin
|
||||
sample_now <= 1'b0;
|
||||
sample_cntr <= sample_cntr + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
reg [1:0] state;
|
||||
reg [3:0] held_bits;
|
||||
parameter WAITING = 2'b00, READING = 2'b01, STOP = 2'b10, RECOVER = 2'b11;
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
state <= WAITING;
|
||||
held_bits <= 0;
|
||||
rx_shift <= 0;
|
||||
rx_data_fresh <= 1'b0;
|
||||
rx_data <= 0;
|
||||
end
|
||||
else begin
|
||||
rx_data_fresh <= 1'b0;
|
||||
case (state)
|
||||
WAITING : begin
|
||||
// wait for a start bit (0)
|
||||
if (!slew & sample_now && !last_rxd) begin
|
||||
state <= READING;
|
||||
held_bits <= 0;
|
||||
end
|
||||
end
|
||||
READING : begin
|
||||
// gather data bits
|
||||
if (sample_now) begin
|
||||
rx_shift <= {last_rxd,rx_shift[7:1]};
|
||||
held_bits <= held_bits + 1'b1;
|
||||
if (held_bits == 4'h7) state <= STOP;
|
||||
end
|
||||
end
|
||||
STOP : begin
|
||||
// verify stop bit (1)
|
||||
if (sample_now) begin
|
||||
if (last_rxd) begin
|
||||
rx_data <= rx_shift;
|
||||
rx_data_fresh <= 1'b1;
|
||||
state <= WAITING;
|
||||
end
|
||||
else begin
|
||||
// there was a framing error -
|
||||
// discard the byte and work on resync
|
||||
state <= RECOVER;
|
||||
end
|
||||
end
|
||||
end
|
||||
RECOVER : begin
|
||||
// wait for an idle (1) then resume
|
||||
if (sample_now) begin
|
||||
if (last_rxd) state <= WAITING;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
module uart (clk,rst,
|
||||
tx_data,tx_data_valid,tx_data_ack,txd,
|
||||
rx_data,rx_data_fresh,rxd);
|
||||
|
||||
parameter CLK_HZ = 50_000_000;
|
||||
parameter BAUD = 115200;
|
||||
parameter BAUD_DIVISOR = CLK_HZ / BAUD;
|
||||
|
||||
initial begin
|
||||
if (BAUD_DIVISOR > 16'hffff) begin
|
||||
// This rate is too slow for the TX and RX sample
|
||||
// counter resolution
|
||||
$display ("Error - Increase the size of the sample counters");
|
||||
$stop();
|
||||
end
|
||||
end
|
||||
|
||||
output txd;
|
||||
input clk, rst, rxd;
|
||||
input [7:0] tx_data;
|
||||
input tx_data_valid;
|
||||
output tx_data_ack;
|
||||
output [7:0] rx_data;
|
||||
output rx_data_fresh;
|
||||
|
||||
uart_tx utx (
|
||||
.clk(clk),.rst(rst),
|
||||
.tx_data(tx_data),
|
||||
.tx_data_valid(tx_data_valid),
|
||||
.tx_data_ack(tx_data_ack),
|
||||
.txd(txd));
|
||||
|
||||
defparam utx .BAUD_DIVISOR = BAUD_DIVISOR;
|
||||
|
||||
uart_rx urx (
|
||||
.clk(clk),.rst(rst),
|
||||
.rx_data(rx_data),
|
||||
.rx_data_fresh(rx_data_fresh),
|
||||
.rxd(rxd));
|
||||
|
||||
defparam urx .BAUD_DIVISOR = BAUD_DIVISOR;
|
||||
|
||||
endmodule
|
85
Advanced Synthesis Cookbook/communication/uart_hw_test.v
Normal file
85
Advanced Synthesis Cookbook/communication/uart_hw_test.v
Normal file
@ -0,0 +1,85 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 02-16-2007
|
||||
module uart_hw_test (clk,rst_n,txd,rxd);
|
||||
|
||||
input clk,rst_n;
|
||||
input rxd;
|
||||
output txd;
|
||||
|
||||
reg [7:0] tx_data;
|
||||
reg tx_data_valid;
|
||||
wire tx_data_ack;
|
||||
wire txd,rxd;
|
||||
wire [7:0] rx_data;
|
||||
wire rx_data_fresh;
|
||||
|
||||
reg [7:0] rst_cntr;
|
||||
reg rst;
|
||||
always @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
rst_cntr <= 0;
|
||||
rst <= 1'b1;
|
||||
end
|
||||
else begin
|
||||
if (&rst_cntr) begin
|
||||
rst <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
rst <= 1'b1;
|
||||
rst_cntr <= rst_cntr + 1'b1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
uart u (.clk(clk),
|
||||
.rst(rst),
|
||||
.tx_data(tx_data),
|
||||
.tx_data_valid(tx_data_valid),
|
||||
.tx_data_ack(tx_data_ack),
|
||||
.txd(txd),
|
||||
.rx_data(rx_data),
|
||||
.rx_data_fresh(rx_data_fresh),
|
||||
.rxd(rxd));
|
||||
|
||||
defparam u .CLK_HZ = 100_000_000;
|
||||
defparam u .BAUD = 115200;
|
||||
|
||||
// add one to each RX byte and send it out again
|
||||
always @(posedge clk) begin
|
||||
if (rst) begin
|
||||
tx_data <= 1'b0;
|
||||
tx_data_valid <= 1'b0;
|
||||
end
|
||||
else begin
|
||||
if (rx_data_fresh) begin
|
||||
tx_data <= rx_data + 1'b1;
|
||||
tx_data_valid <= 1'b1;
|
||||
end
|
||||
else if (tx_data_ack) begin
|
||||
tx_data_valid <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
97
Advanced Synthesis Cookbook/communication/uart_tb.v
Normal file
97
Advanced Synthesis Cookbook/communication/uart_tb.v
Normal file
@ -0,0 +1,97 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
module uart_tb ();
|
||||
|
||||
reg clk, rst;
|
||||
reg [7:0] tx_data;
|
||||
reg tx_data_valid;
|
||||
wire tx_data_ack;
|
||||
wire txd,rxd;
|
||||
wire [7:0] rx_data;
|
||||
wire rx_data_fresh;
|
||||
|
||||
uart u (
|
||||
.clk(clk),
|
||||
.rst(rst),
|
||||
.tx_data(tx_data),
|
||||
.tx_data_valid(tx_data_valid),
|
||||
.tx_data_ack(tx_data_ack),
|
||||
.txd(txd),
|
||||
.rx_data(rx_data),
|
||||
.rx_data_fresh(rx_data_fresh),
|
||||
.rxd(rxd)
|
||||
);
|
||||
|
||||
assign rxd = txd;
|
||||
|
||||
initial begin
|
||||
clk = 0;
|
||||
rst = 1;
|
||||
tx_data_valid = 1'b0;
|
||||
@(posedge clk);
|
||||
@(negedge clk);
|
||||
rst = 0;
|
||||
end
|
||||
|
||||
always begin
|
||||
#50 clk = ~clk;
|
||||
end
|
||||
|
||||
// tx data driver
|
||||
always begin
|
||||
#1000 @(negedge clk) tx_data_valid = $random;
|
||||
end
|
||||
|
||||
always @(posedge clk) begin
|
||||
if (rst) tx_data <= "a";
|
||||
else if (tx_data_ack) begin
|
||||
if (tx_data == "z") tx_data <= "a";
|
||||
else tx_data <= tx_data + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
// rx data checker
|
||||
reg fail = 0;
|
||||
reg [7:0] expected_rx;
|
||||
always @(posedge clk) begin
|
||||
if (rst) expected_rx <= "a";
|
||||
else if (rx_data_fresh) begin
|
||||
if (rx_data !== expected_rx) begin
|
||||
$display ("Mismatch at time %d",$time);
|
||||
fail = 1;
|
||||
#1000
|
||||
$stop();
|
||||
end
|
||||
if (expected_rx == "z") expected_rx <= "a";
|
||||
else expected_rx <= expected_rx + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
initial begin
|
||||
#1000000 if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
endmodule
|
101
Advanced Synthesis Cookbook/communication/x4_decoder_8b10b.v
Normal file
101
Advanced Synthesis Cookbook/communication/x4_decoder_8b10b.v
Normal file
@ -0,0 +1,101 @@
|
||||
// Copyright 2009 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module x4_decoder_8b10b (
|
||||
input clk,
|
||||
input rst,
|
||||
input [39:0] din_dat, // 10b data input
|
||||
output [31:0] dout_dat, // data out
|
||||
output [3:0] dout_k, // special code
|
||||
output [3:0] dout_kerr, // coding mistake detected
|
||||
output [3:0] dout_rderr, // running disparity mistake detected
|
||||
output [3:0] dout_rdcomb, // running dispartiy output (comb)
|
||||
output [3:0] dout_rdreg // running disparity output (reg)
|
||||
);
|
||||
|
||||
parameter METHOD = 1;
|
||||
|
||||
decoder_8b10b dec3(
|
||||
.clk (clk),
|
||||
.rst (rst),
|
||||
.din_ena(1'b1), // Data (or code) input enable
|
||||
.din_dat(din_dat[39 : 30]), // 8b data in
|
||||
.din_rd(dout_rdreg[0]), // running disparity input
|
||||
.dout_val(),
|
||||
.dout_kerr(dout_kerr[3]),
|
||||
.dout_dat(dout_dat[31 : 24]), // data out
|
||||
.dout_k(dout_k[3]),
|
||||
.dout_rderr(dout_rderr[3]),
|
||||
.dout_rdcomb(dout_rdcomb[3]), // running disparity output (comb)
|
||||
.dout_rdreg(dout_rdreg[3]) // running disparity output (reg)
|
||||
);
|
||||
defparam dec3.METHOD = METHOD;
|
||||
|
||||
decoder_8b10b dec2(
|
||||
.clk (clk),
|
||||
.rst (rst),
|
||||
.din_ena(1'b1), // Data (or code) input enable
|
||||
.din_dat(din_dat[29 : 20]), // 8b data in
|
||||
.din_rd(dout_rdcomb[3]), // running disparity input
|
||||
.dout_val(),
|
||||
.dout_kerr(dout_kerr[2]),
|
||||
.dout_dat(dout_dat[23 : 16]), // data out
|
||||
.dout_k(dout_k[2]),
|
||||
.dout_rderr(dout_rderr[2]),
|
||||
.dout_rdcomb(dout_rdcomb[2]), // running disparity output (comb)
|
||||
.dout_rdreg(dout_rdreg[2]) // running disparity output (reg)
|
||||
);
|
||||
defparam dec2.METHOD = METHOD;
|
||||
|
||||
decoder_8b10b dec1(
|
||||
.clk (clk),
|
||||
.rst (rst),
|
||||
.din_ena(1'b1), // Data (or code) input enable
|
||||
.din_dat(din_dat[19 : 10]), // 8b data in
|
||||
.din_rd(dout_rdcomb[2]), // running disparity input
|
||||
.dout_val(),
|
||||
.dout_kerr(dout_kerr[1]),
|
||||
.dout_dat(dout_dat[15 : 8]), // data out
|
||||
.dout_k(dout_k[1]),
|
||||
.dout_rderr(dout_rderr[1]),
|
||||
.dout_rdcomb(dout_rdcomb[1]), // running disparity output (comb)
|
||||
.dout_rdreg(dout_rdreg[1]) // running disparity output (reg)
|
||||
);
|
||||
defparam dec1.METHOD = METHOD;
|
||||
|
||||
decoder_8b10b dec0(
|
||||
.clk (clk),
|
||||
.rst (rst),
|
||||
.din_ena(1'b1), // Data (or code) input enable
|
||||
.din_dat(din_dat[9 : 0]), // 8b data in
|
||||
.din_rd(dout_rdcomb[1]), // running disparity input
|
||||
.dout_val(),
|
||||
.dout_kerr(dout_kerr[0]),
|
||||
.dout_dat(dout_dat[7 : 0]), // data out
|
||||
.dout_k(dout_k[0]),
|
||||
.dout_rderr(dout_rderr[0]),
|
||||
.dout_rdcomb(dout_rdcomb[0]), // running disparity output (comb)
|
||||
.dout_rdreg(dout_rdreg[0]) // running disparity output (reg)
|
||||
);
|
||||
defparam dec0.METHOD = METHOD;
|
||||
|
||||
endmodule
|
93
Advanced Synthesis Cookbook/communication/x4_encoder_8b10b.v
Normal file
93
Advanced Synthesis Cookbook/communication/x4_encoder_8b10b.v
Normal file
@ -0,0 +1,93 @@
|
||||
// Copyright 2009 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module x4_encoder_8b10b (
|
||||
input clk,
|
||||
input rst,
|
||||
input [3:0] kin_ena, // Data in is a special code, not all are legal.
|
||||
input [31 : 0] ein_dat, // 8b data in
|
||||
output [39 : 0] eout_dat // data out
|
||||
);
|
||||
|
||||
parameter METHOD = 1;
|
||||
|
||||
wire [3:0] eout_rdcomb;
|
||||
wire [3:0] eout_rdreg;
|
||||
wire [3:0] eout_val; // not used, since ein_ena not used in cascaded version
|
||||
|
||||
encoder_8b10b enc3(
|
||||
.clk (clk),
|
||||
.rst (rst),
|
||||
.kin_ena(kin_ena[3]), // Data in is a special code, not all are legal.
|
||||
.ein_ena(1'b1), // Data (or code) input enable
|
||||
.ein_dat(ein_dat[31 : 24]), // 8b data in
|
||||
.ein_rd(eout_rdreg[0]), // running disparity input
|
||||
.eout_val(eout_val[3]), // data out is valid
|
||||
.eout_dat(eout_dat[39 : 30]), // data out
|
||||
.eout_rdcomb(eout_rdcomb[3]), // running disparity output (comb)
|
||||
.eout_rdreg(eout_rdreg[3]) // running disparity output (reg)
|
||||
);
|
||||
defparam enc3.METHOD = METHOD;
|
||||
|
||||
encoder_8b10b enc2(
|
||||
.clk (clk),
|
||||
.rst (rst),
|
||||
.kin_ena(kin_ena[2]), // Data in is a special code, not all are legal.
|
||||
.ein_ena(1'b1), // Data (or code) input enable
|
||||
.ein_dat(ein_dat[23 : 16]), // 8b data in
|
||||
.ein_rd(eout_rdcomb[3]), // running disparity input
|
||||
.eout_val(eout_val[2]), // data out is valid
|
||||
.eout_dat(eout_dat[29 : 20]), // data out
|
||||
.eout_rdcomb(eout_rdcomb[2]), // running disparity output (comb)
|
||||
.eout_rdreg(eout_rdreg[2]) // running disparity output (reg)
|
||||
);
|
||||
defparam enc2.METHOD = METHOD;
|
||||
|
||||
encoder_8b10b enc1(
|
||||
.clk (clk),
|
||||
.rst (rst),
|
||||
.kin_ena(kin_ena[1]), // Data in is a special code, not all are legal.
|
||||
.ein_ena(1'b1), // Data (or code) input enable
|
||||
.ein_dat(ein_dat[15 : 8]), // 8b data in
|
||||
.ein_rd(eout_rdcomb[2]), // running disparity input
|
||||
.eout_val(eout_val[1]), // data out is valid
|
||||
.eout_dat(eout_dat[19 : 10]), // data out
|
||||
.eout_rdcomb(eout_rdcomb[1]), // running disparity output (comb)
|
||||
.eout_rdreg(eout_rdreg[1]) // running disparity output (reg)
|
||||
);
|
||||
defparam enc1.METHOD = METHOD;
|
||||
|
||||
encoder_8b10b enc0(
|
||||
.clk (clk),
|
||||
.rst (rst),
|
||||
.kin_ena(kin_ena[0]), // Data in is a special code, not all are legal.
|
||||
.ein_ena(1'b1), // Data (or code) input enable
|
||||
.ein_dat(ein_dat[7 : 0]), // 8b data in
|
||||
.ein_rd(eout_rdcomb[1]), // running disparity input
|
||||
.eout_val(eout_val[0]), // data out is valid
|
||||
.eout_dat(eout_dat[9 : 0]), // data out
|
||||
.eout_rdcomb(eout_rdcomb[0]), // running disparity output (comb)
|
||||
.eout_rdreg(eout_rdreg[0]) // running disparity output (reg)
|
||||
);
|
||||
defparam enc0.METHOD = METHOD;
|
||||
|
||||
endmodule
|
182
Advanced Synthesis Cookbook/communication/x4_encoder_tb.sv
Normal file
182
Advanced Synthesis Cookbook/communication/x4_encoder_tb.sv
Normal file
@ -0,0 +1,182 @@
|
||||
// Copyright 2011 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module x4_encoder_tb ();
|
||||
|
||||
reg clk;
|
||||
reg rst_n;
|
||||
reg kin_ena;
|
||||
reg ein_ena;
|
||||
reg [7:0] ein_dat;
|
||||
wire ein_rd;
|
||||
|
||||
wire eout_val_a;
|
||||
wire [9:0] eout_dat_a;
|
||||
wire eout_rdcomb_a, eout_rdreg_a;
|
||||
|
||||
///////////////////////////////////////////
|
||||
// x1 test units
|
||||
///////////////////////////////////////////
|
||||
|
||||
encoder_8b10b dut_a (
|
||||
.clk(clk),
|
||||
.rst(!rst_n),
|
||||
.kin_ena(kin_ena),
|
||||
.ein_ena(ein_ena),
|
||||
.ein_dat(ein_dat),
|
||||
.ein_rd(ein_rd),
|
||||
.eout_val(eout_val_a),
|
||||
.eout_dat(eout_dat_a),
|
||||
.eout_rdcomb(eout_rdcomb_a),
|
||||
.eout_rdreg(eout_rdreg_a)
|
||||
);
|
||||
assign ein_rd = eout_rdreg_a;
|
||||
|
||||
wire k_c,kerr_c,rderr_c;
|
||||
wire [7:0] dat_c;
|
||||
|
||||
decoder_8b10b dut_c (
|
||||
.clk(clk),
|
||||
.rst(!rst_n),
|
||||
.din_ena(1'b1),
|
||||
.din_dat(eout_dat_a),
|
||||
.din_rd(rdreg_c),
|
||||
.dout_val(),
|
||||
.dout_dat(dat_c),
|
||||
.dout_k(k_c),
|
||||
.dout_kerr(kerr_c),
|
||||
.dout_rderr(rderr_c),
|
||||
.dout_rdcomb(),
|
||||
.dout_rdreg(rdreg_c)
|
||||
);
|
||||
|
||||
///////////////////////////////////////////
|
||||
// x4 test units
|
||||
///////////////////////////////////////////
|
||||
|
||||
reg x4_clk;
|
||||
reg [31:0] x4_ein_dat;
|
||||
reg [3:0] x4_kin_ena;
|
||||
wire [39:0] x4_eout_dat;
|
||||
|
||||
always @(posedge clk or negedge rst_n) begin
|
||||
if (!rst_n) begin
|
||||
x4_ein_dat <= 0;
|
||||
x4_kin_ena <= 0;
|
||||
end
|
||||
else begin
|
||||
x4_ein_dat <= (x4_ein_dat << 8) | ein_dat;
|
||||
x4_kin_ena <= (x4_kin_ena << 1) | kin_ena;
|
||||
end
|
||||
end
|
||||
|
||||
x4_encoder_8b10b dut_b (
|
||||
.clk(x4_clk),
|
||||
.rst(!rst_n),
|
||||
.kin_ena(x4_kin_ena), // Data in is a special code, not all are legal.
|
||||
.ein_dat(x4_ein_dat), // 8b data in
|
||||
.eout_dat(x4_eout_dat) // data out
|
||||
);
|
||||
|
||||
// break up result for visibility
|
||||
wire [9:0] w0,w1,w2,w3;
|
||||
assign {w0,w1,w2,w3} = x4_eout_dat;
|
||||
|
||||
wire [31:0] x4_dat_recovered;
|
||||
wire [3:0] x4_k_recovered;
|
||||
wire [3:0] x4_kerr,x4_rderr;
|
||||
|
||||
x4_decoder_8b10b dut_d(
|
||||
.clk(x4_clk),
|
||||
.rst(!rst_n),
|
||||
.din_dat(x4_eout_dat), // 10b data input
|
||||
.dout_dat(x4_dat_recovered), // data out
|
||||
.dout_k(x4_k_recovered), // special code
|
||||
.dout_kerr(x4_kerr), // coding mistake detected
|
||||
.dout_rderr(x4_rderr), // running disparity mistake detected
|
||||
.dout_rdcomb(), // running dispartiy output (comb)
|
||||
.dout_rdreg() // running disparity output (reg)
|
||||
);
|
||||
|
||||
///////////////////////////////////////////
|
||||
// not all data for transmit is legal.
|
||||
///////////////////////////////////////////
|
||||
reg [3:0] tmp;
|
||||
always @(negedge clk or negedge rst_n) begin
|
||||
ein_ena = $random;
|
||||
kin_ena = !ein_ena;
|
||||
tmp = $random % 4'hd;
|
||||
|
||||
if (kin_ena) begin
|
||||
case (tmp)
|
||||
// valid K signals
|
||||
4'h0 : ein_dat = 8'b000_11100;
|
||||
4'h1 : ein_dat = 8'b000_11100;
|
||||
4'h2 : ein_dat = 8'b001_11100;
|
||||
4'h3 : ein_dat = 8'b010_11100;
|
||||
4'h4 : ein_dat = 8'b011_11100;
|
||||
4'h5 : ein_dat = 8'b100_11100;
|
||||
4'h6 : ein_dat = 8'b101_11100;
|
||||
4'h7 : ein_dat = 8'b110_11100;
|
||||
4'h8 : ein_dat = 8'b111_11100;
|
||||
4'h9 : ein_dat = 8'b111_10111;
|
||||
4'ha : ein_dat = 8'b111_11011;
|
||||
4'hb : ein_dat = 8'b111_11101;
|
||||
4'hc : ein_dat = 8'b111_11110;
|
||||
// 4'hd : ein_dat = 8'b111_11111;
|
||||
default : ein_dat = 0;
|
||||
endcase
|
||||
end
|
||||
else
|
||||
ein_dat = $random;
|
||||
end
|
||||
|
||||
///////////////////////////////////////////
|
||||
// clock driver
|
||||
///////////////////////////////////////////
|
||||
initial begin
|
||||
clk = 0;
|
||||
x4_clk = 1;
|
||||
rst_n = 1;
|
||||
#1 rst_n = 0;
|
||||
@(negedge clk) rst_n = 1;
|
||||
end
|
||||
|
||||
always begin
|
||||
#5 clk = ~clk;
|
||||
end
|
||||
|
||||
always begin
|
||||
@(posedge clk);
|
||||
if (!rst_n) begin
|
||||
@(negedge clk);
|
||||
@(negedge clk);
|
||||
end
|
||||
@(negedge clk);
|
||||
x4_clk = ~x4_clk;
|
||||
@(negedge clk);
|
||||
@(negedge clk);
|
||||
x4_clk = ~x4_clk;
|
||||
@(negedge clk);
|
||||
end
|
||||
|
||||
endmodule
|
129
Advanced Synthesis Cookbook/compare/carry_and.v
Normal file
129
Advanced Synthesis Cookbook/compare/carry_and.v
Normal file
@ -0,0 +1,129 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 03-01-2006
|
||||
|
||||
module carry_and (dat,out);
|
||||
|
||||
parameter WIDTH = 32;
|
||||
parameter METHOD = 4;
|
||||
|
||||
input [WIDTH-1:0] dat;
|
||||
output out;
|
||||
|
||||
// figure out pairs and triples of inputs
|
||||
localparam NEXT_EVEN_WIDTH = (WIDTH & 1) ? WIDTH + 1 : WIDTH;
|
||||
localparam HALF_WIDTH = NEXT_EVEN_WIDTH >> 1;
|
||||
localparam NEXT_DIV3_WIDTH = WIDTH + (((WIDTH % 3) & 1) << 1) + (((WIDTH % 3) & 2) >> 1);
|
||||
localparam THIRD_WIDTH = NEXT_DIV3_WIDTH / 3;
|
||||
|
||||
wire [WIDTH + 2 : 0] ext_dat = {3'b111,dat};
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
if (METHOD == 0) begin
|
||||
///////////////////////
|
||||
// Generic style
|
||||
///////////////////////
|
||||
assign out = &dat;
|
||||
end
|
||||
else if (METHOD == 1) begin
|
||||
///////////////////////
|
||||
// 1 bit per cell carry chain
|
||||
///////////////////////
|
||||
wire [WIDTH:0] result;
|
||||
assign result = dat + 1'b1;
|
||||
assign out = result[WIDTH];
|
||||
end
|
||||
else if (METHOD == 2) begin
|
||||
////////////////////////////////
|
||||
// 2 bit per cell carry chain
|
||||
////////////////////////////////
|
||||
wire [HALF_WIDTH-1:0] pairs;
|
||||
wire [HALF_WIDTH:0] result;
|
||||
|
||||
assign pairs = ext_dat[HALF_WIDTH-1:0] &
|
||||
ext_dat[2*HALF_WIDTH-1:HALF_WIDTH];
|
||||
assign result = pairs + 1'b1;
|
||||
assign out = result[HALF_WIDTH];
|
||||
end
|
||||
else if (METHOD == 3) begin
|
||||
////////////////////////////////
|
||||
// 3 bit per cell carry chain
|
||||
// may not absorb fully.
|
||||
// it will also be very tempting
|
||||
// for synthesit to unmap to 6 LUT.
|
||||
// Use Method = 4;
|
||||
////////////////////////////////
|
||||
wire [THIRD_WIDTH-1:0] triplets;
|
||||
wire [THIRD_WIDTH:0] result;
|
||||
|
||||
assign triplets = ext_dat[THIRD_WIDTH-1:0] &
|
||||
ext_dat[2*THIRD_WIDTH-1:THIRD_WIDTH] &
|
||||
ext_dat[3*THIRD_WIDTH-1:2*THIRD_WIDTH];
|
||||
assign result = triplets + 1'b1;
|
||||
assign out = result[THIRD_WIDTH];
|
||||
end
|
||||
else if (METHOD == 4) begin
|
||||
//////////////////////////////////////////
|
||||
// 3 bit per cell Wide AND carry chain
|
||||
// WYSIWYG version
|
||||
//////////////////////////////////////////
|
||||
wire [THIRD_WIDTH:0] result;
|
||||
wire [THIRD_WIDTH+1:0] cin;
|
||||
|
||||
assign cin[0] = 1'b0;
|
||||
|
||||
for (i=0; i<THIRD_WIDTH; i=i+1)
|
||||
begin : third
|
||||
stratixii_lcell_comb w (
|
||||
.dataa(1'b0),
|
||||
.datab(ext_dat[i*3+0]),
|
||||
.datac(ext_dat[i*3+1]),
|
||||
.datad(ext_dat[i*3+2]),
|
||||
|
||||
// unused
|
||||
.datae(1'b0),
|
||||
.dataf(1'b0),
|
||||
.datag(1'b0),
|
||||
|
||||
.cin(cin[i]),
|
||||
.sumout(result[i]),
|
||||
.cout(cin[i+1]),
|
||||
|
||||
.sharein(1'b0),
|
||||
.combout(),
|
||||
.shareout()
|
||||
);
|
||||
|
||||
defparam w .shared_arith = "off";
|
||||
defparam w .extended_lut = "off";
|
||||
|
||||
// 1 + B&C&D (quad 3 is inverted)
|
||||
defparam w .lut_mask =
|
||||
i == 0 ? 64'h000000000000c000 :
|
||||
64'h0000ffff0000c000;
|
||||
end
|
||||
assign out = cin[THIRD_WIDTH];
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
45
Advanced Synthesis Cookbook/compare/carry_and_speed_test.v
Normal file
45
Advanced Synthesis Cookbook/compare/carry_and_speed_test.v
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module carry_and_speed_test (dat_i,out,clk);
|
||||
parameter WIDTH = 16;
|
||||
parameter METHOD = 4;
|
||||
|
||||
input clk;
|
||||
input [WIDTH-1:0] dat_i;
|
||||
output out;
|
||||
|
||||
reg [WIDTH-1:0] dat_r;
|
||||
reg out;
|
||||
wire out_c;
|
||||
|
||||
carry_and ca (.dat(dat_r),.out(out_c));
|
||||
defparam ca .WIDTH = WIDTH;
|
||||
defparam ca .METHOD = METHOD;
|
||||
|
||||
always @(posedge clk) begin
|
||||
dat_r <= dat_i;
|
||||
out <= out_c;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
67
Advanced Synthesis Cookbook/compare/carry_and_tb.v
Normal file
67
Advanced Synthesis Cookbook/compare/carry_and_tb.v
Normal file
@ -0,0 +1,67 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module carry_and_tb ();
|
||||
|
||||
parameter WIDTH = 10;
|
||||
|
||||
reg [WIDTH-1:0] dat;
|
||||
reg fail;
|
||||
|
||||
wire aa,bb,cc,dd,ee;
|
||||
|
||||
carry_and a (.dat(dat),.out(aa));
|
||||
defparam a .WIDTH = WIDTH;
|
||||
defparam a .METHOD = 0;
|
||||
carry_and b (.dat(dat),.out(bb));
|
||||
defparam b .WIDTH = WIDTH;
|
||||
defparam b .METHOD = 1;
|
||||
carry_and c (.dat(dat),.out(cc));
|
||||
defparam c .WIDTH = WIDTH;
|
||||
defparam c .METHOD = 2;
|
||||
carry_and d (.dat(dat),.out(dd));
|
||||
defparam d .WIDTH = WIDTH;
|
||||
defparam d .METHOD = 3;
|
||||
carry_and e (.dat(dat),.out(ee));
|
||||
defparam e .WIDTH = WIDTH;
|
||||
defparam e .METHOD = 4;
|
||||
|
||||
|
||||
initial begin
|
||||
dat = 0;
|
||||
fail = 0;
|
||||
|
||||
#100000 if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
|
||||
always begin
|
||||
#50 dat = {$random,$random};
|
||||
|
||||
#50 if (aa !== bb || aa !== cc || aa !== dd || aa !==ee) begin
|
||||
$display ("Mismatch at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
93
Advanced Synthesis Cookbook/compare/compare_masks.inc
Normal file
93
Advanced Synthesis Cookbook/compare/compare_masks.inc
Normal file
@ -0,0 +1,93 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function [15:0] dcb_less_const_mask;
|
||||
input [2:0] const_val;
|
||||
integer n;
|
||||
begin
|
||||
for (n=0; n<16; n=n+1)
|
||||
begin
|
||||
// (n >> 1) because the LSB A is unused
|
||||
dcb_less_const_mask[n] = ((n>>1) < const_val) ? 1 : 0;
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [15:0] dcb_eq_const_mask;
|
||||
input [2:0] const_val;
|
||||
integer n;
|
||||
begin
|
||||
for (n=0; n<16; n=n+1)
|
||||
begin
|
||||
// (n >> 1) because the LSB A is unused
|
||||
dcb_eq_const_mask[n] = ((n>>1) == const_val) ? 1 : 0;
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [15:0] dc_eq_const_mask;
|
||||
input [1:0] const_val;
|
||||
integer n;
|
||||
begin
|
||||
for (n=0; n<16; n=n+1)
|
||||
begin
|
||||
// (n >> 2) because the LSB A,B both unused
|
||||
dc_eq_const_mask[n] = ((n>>2) == const_val) ? 1 : 0;
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [15:0] dc_greater_const_mask;
|
||||
input [1:0] const_val;
|
||||
integer n;
|
||||
begin
|
||||
for (n=0; n<16; n=n+1)
|
||||
begin
|
||||
// (n >> 2) because the LSB A,B both unused
|
||||
dc_greater_const_mask[n] = ((n>>2) > const_val) ? 1 : 0;
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [15:0] dc_ge_const_mask;
|
||||
input [1:0] const_val;
|
||||
integer n;
|
||||
begin
|
||||
for (n=0; n<16; n=n+1)
|
||||
begin
|
||||
// (n >> 2) because the LSB A,B both unused
|
||||
dc_ge_const_mask[n] = ((n>>2) >= const_val) ? 1 : 0;
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [15:0] dc_less_const_mask;
|
||||
input [1:0] const_val;
|
||||
integer n;
|
||||
begin
|
||||
for (n=0; n<16; n=n+1)
|
||||
begin
|
||||
// (n >> 2) because the LSB A,B both unused
|
||||
dc_less_const_mask[n] = ((n>>2) < const_val) ? 1 : 0;
|
||||
end
|
||||
end
|
||||
endfunction
|
170
Advanced Synthesis Cookbook/compare/compare_tb.v
Normal file
170
Advanced Synthesis Cookbook/compare/compare_tb.v
Normal file
@ -0,0 +1,170 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module compare_tb ();
|
||||
|
||||
parameter WIDTH = 64;
|
||||
parameter CONST_X = 64'h123456781234567a;
|
||||
|
||||
wire a,b,c,d,e;
|
||||
reg [WIDTH-1:0] dat;
|
||||
reg fail;
|
||||
|
||||
less_than_const ca (.dat(dat),.out(a));
|
||||
defparam ca .WIDTH = WIDTH;
|
||||
defparam ca .METHOD = 0;
|
||||
defparam ca .CONST_VAL = CONST_X;
|
||||
less_than_const cb (.dat(dat),.out(b));
|
||||
defparam cb .WIDTH = WIDTH;
|
||||
defparam cb .METHOD = 1;
|
||||
defparam cb .CONST_VAL = CONST_X;
|
||||
less_than_const cc (.dat(dat),.out(c));
|
||||
defparam cc .WIDTH = WIDTH;
|
||||
defparam cc .METHOD = 2;
|
||||
defparam cc .CONST_VAL = CONST_X;
|
||||
less_than_const cd (.dat(dat),.out(d));
|
||||
defparam cd .WIDTH = WIDTH;
|
||||
defparam cd .METHOD = 3;
|
||||
defparam cd .CONST_VAL = CONST_X;
|
||||
less_than_const ce (.dat(dat),.out(e));
|
||||
defparam ce .WIDTH = WIDTH;
|
||||
defparam ce .METHOD = 4;
|
||||
defparam ce .CONST_VAL = CONST_X;
|
||||
|
||||
parameter WIDTH_2 = 9;
|
||||
parameter CONST_Y = 9'b100101010;
|
||||
|
||||
wire q,r,s,t,u;
|
||||
reg [WIDTH_2-1:0] dat_2;
|
||||
|
||||
less_than_const da (.dat(dat_2),.out(q));
|
||||
defparam da .WIDTH = WIDTH_2;
|
||||
defparam da .METHOD = 0;
|
||||
defparam da .CONST_VAL = CONST_Y;
|
||||
less_than_const db (.dat(dat_2),.out(r));
|
||||
defparam db .WIDTH = WIDTH_2;
|
||||
defparam db .METHOD = 1;
|
||||
defparam db .CONST_VAL = CONST_Y;
|
||||
less_than_const dc (.dat(dat_2),.out(s));
|
||||
defparam dc .WIDTH = WIDTH_2;
|
||||
defparam dc .METHOD = 2;
|
||||
defparam dc .CONST_VAL = CONST_Y;
|
||||
less_than_const dd (.dat(dat_2),.out(t));
|
||||
defparam dd .WIDTH = WIDTH_2;
|
||||
defparam dd .METHOD = 3;
|
||||
defparam dd .CONST_VAL = CONST_Y;
|
||||
less_than_const de (.dat(dat_2),.out(u));
|
||||
defparam de .WIDTH = WIDTH_2;
|
||||
defparam de .METHOD = 4;
|
||||
defparam de .CONST_VAL = CONST_Y;
|
||||
|
||||
reg over;
|
||||
wire w,x,y,z;
|
||||
parameter UPPER = 9'b011001001;
|
||||
parameter LOWER = 9'b000010010;
|
||||
|
||||
over_under oa (.dat(dat_2),.over(over),.out(w));
|
||||
defparam oa .WIDTH = WIDTH_2;
|
||||
defparam oa .METHOD = 0;
|
||||
defparam oa .UPPER_BOUND = UPPER;
|
||||
defparam oa .LOWER_BOUND = LOWER;
|
||||
over_under ob (.dat(dat_2),.over(over),.out(x));
|
||||
defparam ob .WIDTH = WIDTH_2;
|
||||
defparam ob .METHOD = 1;
|
||||
defparam ob .UPPER_BOUND = UPPER;
|
||||
defparam ob .LOWER_BOUND = LOWER;
|
||||
over_under oc (.dat(dat_2),.over(over),.out(y));
|
||||
defparam oc .WIDTH = WIDTH_2;
|
||||
defparam oc .METHOD = 2;
|
||||
defparam oc .UPPER_BOUND = UPPER;
|
||||
defparam oc .LOWER_BOUND = LOWER;
|
||||
over_under od (.dat(dat_2),.over(over),.out(z));
|
||||
defparam od .WIDTH = WIDTH_2;
|
||||
defparam od .METHOD = 3;
|
||||
defparam od .UPPER_BOUND = UPPER;
|
||||
defparam od .LOWER_BOUND = LOWER;
|
||||
|
||||
wire ww,xx,yy,zz;
|
||||
|
||||
parameter UPPER_3 = 8'b11001001;
|
||||
parameter LOWER_3 = 8'b00010010;
|
||||
|
||||
over_under pa (.dat(dat_2),.over(over),.out(ww));
|
||||
defparam pa .WIDTH = WIDTH_2-1;
|
||||
defparam pa .METHOD = 0;
|
||||
defparam pa .UPPER_BOUND = UPPER_3;
|
||||
defparam pa .LOWER_BOUND = LOWER_3;
|
||||
over_under pb (.dat(dat_2),.over(over),.out(xx));
|
||||
defparam pb .WIDTH = WIDTH_2-1;
|
||||
defparam pb .METHOD = 1;
|
||||
defparam pb .UPPER_BOUND = UPPER_3;
|
||||
defparam pb .LOWER_BOUND = LOWER_3;
|
||||
over_under pc (.dat(dat_2),.over(over),.out(yy));
|
||||
defparam pc .WIDTH = WIDTH_2-1;
|
||||
defparam pc .METHOD = 2;
|
||||
defparam pc .UPPER_BOUND = UPPER_3;
|
||||
defparam pc .LOWER_BOUND = LOWER_3;
|
||||
over_under pd (.dat(dat_2),.over(over),.out(zz));
|
||||
defparam pd .WIDTH = WIDTH_2-1;
|
||||
defparam pd .METHOD = 3;
|
||||
defparam pd .UPPER_BOUND = UPPER_3;
|
||||
defparam pd .LOWER_BOUND = LOWER_3;
|
||||
|
||||
|
||||
initial begin
|
||||
dat = 0;
|
||||
dat_2 = 0;
|
||||
over = 0;
|
||||
fail = 0;
|
||||
|
||||
#100000 if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
always begin
|
||||
#50 dat = {$random,$random};
|
||||
dat_2 = $random;
|
||||
over = $random;
|
||||
|
||||
#50 if (a !== b || a !== c || a !== d || a!= e) begin
|
||||
$display ("Mismatch in cx series at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
|
||||
if (q !== r || q !== s || q !== t || q != u) begin
|
||||
$display ("Mismatch in dx series at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
|
||||
if (w !== x || w !== y || w !== z) begin
|
||||
$display ("Mismatch in ox series at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
|
||||
if (ww !== xx || ww !== yy || ww !== zz) begin
|
||||
$display ("Mismatch in px series at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
endmodule
|
4
Advanced Synthesis Cookbook/compare/cook.sh
Normal file
4
Advanced Synthesis Cookbook/compare/cook.sh
Normal file
@ -0,0 +1,4 @@
|
||||
quartus_map --family=stratixii --optimize=speed carry_and_speed_test | tee q.log
|
||||
quartus_fit --fmax=1ghz carry_and_speed_test | tee f.log
|
||||
quartus_tan carry_and_speed_test | tee t.log
|
||||
grep "Longest register to register delay" t.log
|
51
Advanced Synthesis Cookbook/compare/equal_const.v
Normal file
51
Advanced Synthesis Cookbook/compare/equal_const.v
Normal file
@ -0,0 +1,51 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module equal_const (dat,out);
|
||||
|
||||
parameter WIDTH = 8;
|
||||
parameter CONST_VAL = 8'h45;
|
||||
parameter METHOD = 0;
|
||||
|
||||
input [WIDTH-1:0] dat;
|
||||
output out;
|
||||
wire out;
|
||||
|
||||
generate
|
||||
if (METHOD == 0) begin
|
||||
///////////////////////
|
||||
// Generic style
|
||||
///////////////////////
|
||||
assign out = (dat == CONST_VAL);
|
||||
end
|
||||
else if (METHOD == 1) begin
|
||||
////////////////////////////////////////
|
||||
// Carry chain based - 3 bits per cell
|
||||
////////////////////////////////////////
|
||||
carry_and ca (.dat(~dat ^ CONST_VAL),.out(out));
|
||||
defparam ca .WIDTH = WIDTH;
|
||||
defparam ca .METHOD = 4;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
61
Advanced Synthesis Cookbook/compare/equal_const_tb.v
Normal file
61
Advanced Synthesis Cookbook/compare/equal_const_tb.v
Normal file
@ -0,0 +1,61 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module equal_const_tb ();
|
||||
|
||||
parameter WIDTH = 10;
|
||||
parameter CONST_VAL = 10'b1010111010;
|
||||
|
||||
reg [WIDTH-1:0] dat;
|
||||
reg fail;
|
||||
|
||||
wire aa,bb;
|
||||
|
||||
equal_const a (.dat(dat),.out(aa));
|
||||
defparam a .WIDTH = WIDTH;
|
||||
defparam a .METHOD = 0;
|
||||
defparam a .CONST_VAL = CONST_VAL;
|
||||
|
||||
equal_const b (.dat(dat),.out(bb));
|
||||
defparam b .WIDTH = WIDTH;
|
||||
defparam b .METHOD = 1;
|
||||
defparam b .CONST_VAL = CONST_VAL;
|
||||
|
||||
initial begin
|
||||
dat = 0;
|
||||
fail = 0;
|
||||
|
||||
#100000 if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
|
||||
always begin
|
||||
#50 dat = {$random,$random};
|
||||
|
||||
#50 if (aa !== bb) begin
|
||||
$display ("Mismatch at time %d",$time);
|
||||
fail = 1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
41
Advanced Synthesis Cookbook/compare/highest_10.inc
Normal file
41
Advanced Synthesis Cookbook/compare/highest_10.inc
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// helper function to identify
|
||||
// the most significant bit where upper is 1 and
|
||||
// lower is 0.
|
||||
|
||||
function integer highest_10;
|
||||
input integer upper;
|
||||
input integer lower;
|
||||
integer log2_upper;
|
||||
integer j;
|
||||
begin
|
||||
highest_10 = 0;
|
||||
log2_upper = log2 (upper);
|
||||
for (j=0; j<log2_upper; j=j+1)
|
||||
begin
|
||||
if (upper[j] && !lower[j])
|
||||
highest_10 = j;
|
||||
end
|
||||
end
|
||||
endfunction
|
99
Advanced Synthesis Cookbook/compare/in_range.v
Normal file
99
Advanced Synthesis Cookbook/compare/in_range.v
Normal file
@ -0,0 +1,99 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 02-24-2006
|
||||
|
||||
|
||||
module in_range (dat,inr);
|
||||
|
||||
`include "log2.inc"
|
||||
`include "highest_10.inc"
|
||||
|
||||
parameter LOWER_BOUND = 85;
|
||||
parameter UPPER_BOUND = 120;
|
||||
parameter WIDTH = 7;
|
||||
parameter METHOD = 2;
|
||||
|
||||
// identify the most significant bit where UPPER is 1 and
|
||||
// LOWER is 0
|
||||
localparam SPLIT_POINT = highest_10 (UPPER_BOUND,LOWER_BOUND);
|
||||
|
||||
input [WIDTH-1:0] dat;
|
||||
output inr;
|
||||
wire inr;
|
||||
|
||||
genvar i,j;
|
||||
generate
|
||||
if (METHOD == 0) begin
|
||||
////////////////////////////////////////
|
||||
// generic implementation
|
||||
////////////////////////////////////////
|
||||
assign inr = (dat >= LOWER_BOUND && dat < UPPER_BOUND);
|
||||
end
|
||||
else if (METHOD == 1) begin
|
||||
///////////////////////////////////////////////////
|
||||
// use of subtractors to implement the comparison
|
||||
///////////////////////////////////////////////////
|
||||
wire [WIDTH+1:0] result;
|
||||
wire [WIDTH:0] comp_a;
|
||||
assign comp_a = dat-LOWER_BOUND;
|
||||
assign result = comp_a-(UPPER_BOUND-LOWER_BOUND);
|
||||
assign inr = result[WIDTH+1];
|
||||
end
|
||||
else if (METHOD == 2) begin
|
||||
///////////////////////////////////////////////////
|
||||
// Demonstration of over / under / equal technique
|
||||
// illustrated by Paul Q3 2003 slides
|
||||
// No hard structure / chains.
|
||||
///////////////////////////////////////////////////
|
||||
wire ou_out;
|
||||
wire eq_out;
|
||||
|
||||
initial begin
|
||||
$display ("%x",UPPER_BOUND[SPLIT_POINT-1:0]);
|
||||
$display ("%x",LOWER_BOUND[SPLIT_POINT-1:0]);
|
||||
$display ("%x",UPPER_BOUND[WIDTH-1:SPLIT_POINT]);
|
||||
end
|
||||
|
||||
over_under ou (
|
||||
.over(!dat[SPLIT_POINT]),
|
||||
.dat(dat[SPLIT_POINT-1:0]),
|
||||
.out(ou_out)
|
||||
);
|
||||
defparam ou .WIDTH = SPLIT_POINT;
|
||||
defparam ou .METHOD = 0;
|
||||
defparam ou .UPPER_BOUND = UPPER_BOUND [SPLIT_POINT-1 : 0];
|
||||
defparam ou .LOWER_BOUND = LOWER_BOUND [SPLIT_POINT-1 : 0];
|
||||
|
||||
equal_const eq (
|
||||
.dat(dat[WIDTH-1:SPLIT_POINT+1]),
|
||||
.out(eq_out)
|
||||
);
|
||||
defparam eq .WIDTH = WIDTH-SPLIT_POINT-1;
|
||||
defparam eq .CONST_VAL = UPPER_BOUND [WIDTH-1:SPLIT_POINT+1];
|
||||
defparam eq .METHOD = 0;
|
||||
|
||||
assign inr = ou_out & eq_out;
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
69
Advanced Synthesis Cookbook/compare/in_range_tb.v
Normal file
69
Advanced Synthesis Cookbook/compare/in_range_tb.v
Normal file
@ -0,0 +1,69 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
module in_range_tb ();
|
||||
|
||||
parameter LOWER_BOUND = 85;
|
||||
parameter UPPER_BOUND = 120;
|
||||
parameter WIDTH = 7;
|
||||
|
||||
reg [WIDTH-1:0] value;
|
||||
wire inra, inrb, inrc ;
|
||||
|
||||
in_range a (.dat(value),.inr(inra));
|
||||
defparam a .WIDTH = WIDTH;
|
||||
defparam a .LOWER_BOUND = LOWER_BOUND;
|
||||
defparam a .UPPER_BOUND = UPPER_BOUND;
|
||||
defparam a .METHOD = 0;
|
||||
|
||||
in_range b (.dat(value),.inr(inrb));
|
||||
defparam b .WIDTH = WIDTH;
|
||||
defparam b .LOWER_BOUND = LOWER_BOUND;
|
||||
defparam b .UPPER_BOUND = UPPER_BOUND;
|
||||
defparam b .METHOD = 1;
|
||||
|
||||
in_range c (.dat(value),.inr(inrc));
|
||||
defparam c .WIDTH = WIDTH;
|
||||
defparam c .LOWER_BOUND = LOWER_BOUND;
|
||||
defparam c .UPPER_BOUND = UPPER_BOUND;
|
||||
defparam c .METHOD = 2;
|
||||
|
||||
wire too_low = value < LOWER_BOUND;
|
||||
wire too_high = value >= UPPER_BOUND;
|
||||
|
||||
reg fail = 0;
|
||||
|
||||
initial begin
|
||||
value = 0;
|
||||
#100000 if (!fail) $display ("PASS");
|
||||
$stop();
|
||||
end
|
||||
|
||||
always begin
|
||||
#50 value = $random;
|
||||
#50 if (inra !== inrb || inra !== inrc) begin
|
||||
$display ("Mismatch at time %d - val %d",$time,value);
|
||||
fail = 1;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
197
Advanced Synthesis Cookbook/compare/less_than_const.v
Normal file
197
Advanced Synthesis Cookbook/compare/less_than_const.v
Normal file
@ -0,0 +1,197 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 03-01-2006
|
||||
// Check if data is less than constant value
|
||||
|
||||
module less_than_const (dat,out);
|
||||
|
||||
`include "compare_masks.inc"
|
||||
|
||||
parameter CONST_VAL = 64'h123456781234567a;
|
||||
parameter METHOD = 4;
|
||||
parameter WIDTH = 64;
|
||||
|
||||
// derive some more constants for local use
|
||||
localparam NEXT_EVEN_WIDTH = (WIDTH & 1) ? WIDTH + 1 : WIDTH;
|
||||
localparam NEXT_DIV3_WIDTH = WIDTH + (((WIDTH % 3) & 1) << 1) + (((WIDTH % 3) & 2) >> 1);
|
||||
|
||||
localparam HALF_WIDTH = NEXT_EVEN_WIDTH >> 1;
|
||||
localparam THIRD_WIDTH = NEXT_DIV3_WIDTH / 3;
|
||||
|
||||
input [WIDTH-1:0] dat;
|
||||
output out;
|
||||
wire out;
|
||||
|
||||
// Equivalent :
|
||||
// dat < CONST
|
||||
// dat - CONST < 0
|
||||
// dat - CONST sign bit is 1
|
||||
|
||||
genvar i,n;
|
||||
|
||||
// zero pad out the data and constant for convenience
|
||||
wire [WIDTH+5:0] ext_dat = {6'b0,dat};
|
||||
localparam EXT_CONST_VAL = {6'b0,CONST_VAL};
|
||||
|
||||
generate
|
||||
if (METHOD == 0) begin
|
||||
///////////////////////
|
||||
// Generic style
|
||||
///////////////////////
|
||||
assign out = dat < CONST_VAL;
|
||||
end
|
||||
else if (METHOD == 1) begin
|
||||
//////////////////////////////////
|
||||
// Carry chain - one cell per bit + 1
|
||||
//////////////////////////////////
|
||||
wire [WIDTH:0] chain;
|
||||
assign chain = dat - CONST_VAL;
|
||||
assign out = chain[WIDTH];
|
||||
end
|
||||
else if (METHOD == 2) begin
|
||||
//////////////////////////////////
|
||||
// Carry chain - one cell per 2 bits + 1
|
||||
//////////////////////////////////
|
||||
wire [HALF_WIDTH:0] chain;
|
||||
wire [HALF_WIDTH-1 :0] g;
|
||||
wire [HALF_WIDTH-1 :0] p;
|
||||
|
||||
// rephrase in terms of generate and propagate
|
||||
// carry - looking at two bits of the compare at
|
||||
// a time.
|
||||
for (i=0; i<HALF_WIDTH; i=i+1)
|
||||
begin : half
|
||||
wire [1:0] dat_bits = ext_dat[i*2+1 : i*2];
|
||||
wire [1:0] const_bits = EXT_CONST_VAL[i*2+1 : i*2];
|
||||
assign p [i] = (dat_bits == const_bits);
|
||||
assign g [i] = (dat_bits < const_bits);
|
||||
end
|
||||
assign chain = (g | p) + g;
|
||||
assign out = chain[HALF_WIDTH];
|
||||
end
|
||||
else if (METHOD == 3) begin
|
||||
//////////////////////////////////////
|
||||
// Carry chain - one cell per 3 bits
|
||||
// this doesn't actually fit,
|
||||
// but can be rephrased in share
|
||||
// chain.
|
||||
//////////////////////////////////////
|
||||
wire [THIRD_WIDTH:0] chain;
|
||||
wire [THIRD_WIDTH-1 :0] g;
|
||||
wire [THIRD_WIDTH-1 :0] p;
|
||||
|
||||
|
||||
// rephrase in terms of generate and propagate
|
||||
// carry - looking at three bits of the compare at
|
||||
// a time.
|
||||
for (i=0; i<THIRD_WIDTH; i=i+1)
|
||||
begin : third
|
||||
wire [2:0] dat_bits = ext_dat[i*3+2 : i*3];
|
||||
wire [2:0] const_bits = EXT_CONST_VAL[i*3+2 : i*3];
|
||||
assign p [i] = (dat_bits == const_bits);
|
||||
assign g [i] = (dat_bits < const_bits);
|
||||
end
|
||||
assign chain = (g | p) + g;
|
||||
assign out = chain[THIRD_WIDTH];
|
||||
end
|
||||
else if (METHOD == 4) begin
|
||||
//////////////////////////////////////////
|
||||
// WYS share chain - one cell per 3 bits
|
||||
//////////////////////////////////////////
|
||||
wire [THIRD_WIDTH:0] chain;
|
||||
wire [THIRD_WIDTH+1 : 0] cin;
|
||||
wire [THIRD_WIDTH+1 : 0] sin;
|
||||
|
||||
assign cin[0] = 1'b0;
|
||||
assign sin[0] = 1'b0;
|
||||
|
||||
for (i=0; i<=THIRD_WIDTH; i=i+1)
|
||||
begin : third
|
||||
stratixii_lcell_comb w (
|
||||
.dataa(1'b1),
|
||||
.datab(ext_dat[i*3+0]),
|
||||
.datac(ext_dat[i*3+1]),
|
||||
.datad(ext_dat[i*3+2]),
|
||||
|
||||
// unused
|
||||
.datae(1'b0),
|
||||
.dataf(1'b0),
|
||||
.datag(1'b0),
|
||||
|
||||
.cin(cin[i]),
|
||||
.sharein(sin[i]),
|
||||
.sumout(chain[i]),
|
||||
.cout(cin[i+1]),
|
||||
.combout(),
|
||||
.shareout(sin[i+1])
|
||||
);
|
||||
|
||||
defparam w .shared_arith = "on";
|
||||
defparam w .extended_lut = "off";
|
||||
|
||||
// zero the share-out on the last cell
|
||||
defparam w .lut_mask = {
|
||||
16'h0000,
|
||||
(i == THIRD_WIDTH ? 16'h0000 :
|
||||
dcb_less_const_mask(EXT_CONST_VAL[i*3+2:i*3])),
|
||||
16'h0000,
|
||||
dcb_eq_const_mask(EXT_CONST_VAL[i*3+2:i*3])
|
||||
};
|
||||
end
|
||||
|
||||
// this carry out routing track cannot directly
|
||||
// fanout to other cells, it needs another cell
|
||||
// to leave the chain.
|
||||
|
||||
stratixii_lcell_comb tail (
|
||||
.dataa(1'b1),
|
||||
.datab(1'b1),
|
||||
.datac(1'b1),
|
||||
.datad(1'b1),
|
||||
|
||||
// unused
|
||||
.datae(1'b0),
|
||||
.dataf(1'b0),
|
||||
.datag(1'b0),
|
||||
|
||||
.cin(cin[THIRD_WIDTH+1]),
|
||||
.sharein(sin[THIRD_WIDTH+1]),
|
||||
.sumout(out),
|
||||
.cout(),
|
||||
.combout(),
|
||||
.shareout()
|
||||
);
|
||||
|
||||
defparam tail .shared_arith = "on";
|
||||
defparam tail .extended_lut = "off";
|
||||
defparam tail .lut_mask = {
|
||||
16'h0000,
|
||||
16'hffff,
|
||||
16'h0000,
|
||||
16'h0000
|
||||
};
|
||||
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
41
Advanced Synthesis Cookbook/compare/log2.inc
Normal file
41
Advanced Synthesis Cookbook/compare/log2.inc
Normal file
@ -0,0 +1,41 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 12-12-2006
|
||||
// helper function to compute LOG base 2
|
||||
//
|
||||
// NOTE - This is a somewhat abusive definition of LOG2(v) as the
|
||||
// number of bits required to represent "v". So log2(256) will be
|
||||
// 9 rather than 8 (256 = 9'b1_0000_0000). I apologize for any
|
||||
// confusion this may cause.
|
||||
//
|
||||
|
||||
function integer log2;
|
||||
input integer val;
|
||||
begin
|
||||
log2 = 0;
|
||||
while (val > 0) begin
|
||||
val = val >> 1;
|
||||
log2 = log2 + 1;
|
||||
end
|
||||
end
|
||||
endfunction
|
88
Advanced Synthesis Cookbook/compare/match_or_inv.v
Normal file
88
Advanced Synthesis Cookbook/compare/match_or_inv.v
Normal file
@ -0,0 +1,88 @@
|
||||
// Copyright 2007 Altera Corporation. All rights reserved.
|
||||
// Altera products are protected under numerous U.S. and foreign patents,
|
||||
// maskwork rights, copyrights and other intellectual property laws.
|
||||
//
|
||||
// This reference design file, and your use thereof, is subject to and governed
|
||||
// by the terms and conditions of the applicable Altera Reference Design
|
||||
// License Agreement (either as signed by you or found at www.altera.com). By
|
||||
// using this reference design file, you indicate your acceptance of such terms
|
||||
// and conditions between you and Altera Corporation. In the event that you do
|
||||
// not agree with such terms and conditions, you may not use the reference
|
||||
// design file and please promptly destroy any copies you have made.
|
||||
//
|
||||
// This reference design file is being provided on an "as-is" basis and as an
|
||||
// accommodation and therefore all warranties, representations or guarantees of
|
||||
// any kind (whether express, implied or statutory) including, without
|
||||
// limitation, warranties of merchantability, non-infringement, or fitness for
|
||||
// a particular purpose, are specifically disclaimed. By making this reference
|
||||
// design file available, Altera expressly does not recommend, suggest or
|
||||
// require that this reference design file be used in combination with any
|
||||
// other product not provided by Altera.
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// baeckler - 05-13-2005
|
||||
//
|
||||
// Efficient implementation of
|
||||
// (bus_a == bus_b) || (bus_a == ~bus_b);
|
||||
//
|
||||
// for Stratix II hardware. Use optimization technique = speed
|
||||
//
|
||||
|
||||
module match_or_inv (bus_a,bus_b,match_or_inv);
|
||||
|
||||
parameter WIDTH = 32;
|
||||
|
||||
localparam GROUPS_OF_THREE = WIDTH/3;
|
||||
|
||||
input [WIDTH-1:0] bus_a;
|
||||
input [WIDTH-1:0] bus_b;
|
||||
|
||||
output match_or_inv;
|
||||
|
||||
wire [GROUPS_OF_THREE - 1 : 0] groups /* synthesis keep */;
|
||||
wire [GROUPS_OF_THREE + WIDTH-(3*GROUPS_OF_THREE) - 1 : 0] reduced_a;
|
||||
wire [GROUPS_OF_THREE + WIDTH-(3*GROUPS_OF_THREE) - 1 : 0] reduced_b;
|
||||
wire reduced_result;
|
||||
|
||||
genvar i;
|
||||
generate
|
||||
|
||||
// simplify each block of 3 vs 3 bus bits into a six LUT and a 1 bit problem
|
||||
for (i=0; i<GROUPS_OF_THREE; i=i+1)
|
||||
begin : triples
|
||||
wire [2:0] part_a;
|
||||
wire [2:0] part_b;
|
||||
wire m_or_i;
|
||||
assign part_a = bus_a[i*3+2:i*3];
|
||||
assign part_b = bus_b[i*3+2:i*3];
|
||||
assign groups[i] = (part_a == part_b || part_a == ~part_b);
|
||||
assign reduced_a[i] = bus_a[i*3];
|
||||
assign reduced_b[i] = bus_b[i*3];
|
||||
end
|
||||
|
||||
// take care of bus bits when the width isn't a multiple of 3
|
||||
for (i=0; i<WIDTH-(3*GROUPS_OF_THREE); i=i+1)
|
||||
begin : residue
|
||||
assign reduced_a[GROUPS_OF_THREE + i] = bus_a[3*GROUPS_OF_THREE + i];
|
||||
assign reduced_b[GROUPS_OF_THREE + i] = bus_b[3*GROUPS_OF_THREE + i];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// if the remaining problem is big enough tackle it recursively
|
||||
// otherwise just build the gates
|
||||
generate
|
||||
if ((GROUPS_OF_THREE + WIDTH-(3*GROUPS_OF_THREE)) > 3)
|
||||
begin
|
||||
match_or_inv helper (.bus_a(reduced_a),.bus_b(reduced_b),.match_or_inv(reduced_result));
|
||||
defparam helper .WIDTH = (GROUPS_OF_THREE + WIDTH-(3*GROUPS_OF_THREE));
|
||||
end
|
||||
else
|
||||
begin
|
||||
assign reduced_result = (reduced_a == reduced_b || reduced_a == ~reduced_b);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
// Final answer is the & of all 3 input results and the sub problem result
|
||||
assign match_or_inv = (& groups) && reduced_result;
|
||||
|
||||
endmodule
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user