mirror of
https://github.com/pConst/basic_verilog.git
synced 2025-01-14 06:42:54 +08:00
293 lines
7.5 KiB
Systemverilog
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 |