1
0
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:
Konstantin Pavlov (pt) 2015-12-15 22:44:58 +03:00
parent 25b74793e0
commit 40533743d7
450 changed files with 184973 additions and 0 deletions

View 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

View 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

View 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

View 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

View 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

View 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);
}

View 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

View 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

View File

@ -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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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);
}

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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);
}

View 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);
}

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View File

@ -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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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);
}

View 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);
}

View 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

View 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

View 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

View File

@ -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

View 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

View 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

View 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

View 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

View File

@ -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

View 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

View 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

View 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

View 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

View File

@ -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

View 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

View 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

View 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

View File

@ -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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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

View 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