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

172 lines
4.8 KiB
Verilog

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