1
0
mirror of https://github.com/pConst/basic_verilog.git synced 2025-01-14 06:42:54 +08:00
Konstantin Pavlov (pt) 40533743d7 Added altera cookbook
2015-12-15 22:44:58 +03:00

293 lines
7.5 KiB
Systemverilog

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