//
// DECODER.V
//
// Decoder is used to decode the first quadlet.
// The decoder determines the packet type, header length, data payload.
// It is also used to check the destination & broadcast address of the packet.
// The module instantiate 'tcodetable.v'
//
//
module decoder
( //Input
BCLK,
dec, //used to signal the decoder to decode the packet
receive_or_transmit, //to determine the mode ('1' for transmitter)
reset_n,
DATA_IR, //Input from Internal Registers
DATA_DECODE, //Data to be decoded
//Output
data_payload, //determines whether a data payload is with the packet
header_length, //the length of the packet header
decode_error, //high in case of invalid 'tcode' or destination address
// mismatch
decode_complete, //operation complete signal
ADDR_IR,
oenable, //output enable to the Internal Register module
data_dec_out,
broadcast //high when the packet is a broadcast
);
input BCLK,dec,receive_or_transmit,reset_n;
input [31:0] DATA_DECODE;
input [15:0]DATA_IR;
wire d_error;
output data_payload,decode_error,decode_complete, oenable, broadcast;
output[2:0] header_length;
output [7:0]ADDR_IR;
reg decode, broadcast, decode_complete, decode_error;
wire BCLK,dec,reset_n,data_payload,dec_complete;
wire[2:0] header_length;
wire [31:0] DATA_DECODE;
wire [3:0]data_decode1;
wire [15:0]dest_id;
reg oenable;
reg [7:0]ADDR_IR;
reg dest_error, data_flag,decode_en,decode_flag;
reg[15:0]source_ID;
output [3:0]data_dec_out;
assign data_decode1 = DATA_DECODE[7:4]; //
assign dest_id = DATA_DECODE[31:16]; //
//Instantiate the 'tcodetable' module used for the tcode decoding
//tcode determines the possible values of header_length and data_payload
tcodetable t1(dec_complete, d_error, header_length, data_payload, reset_n,decode, data_decode1,data_dec_out);
parameter SOURCEID_ = 8'h 40; //address of Internal Register for source ID
//(bus number, node number)
always @(negedge BCLK)
begin
decode_complete <= dec_complete; //
end
//generation of decode signal to the tcodetable module.
always @(posedge BCLK)
begin
if(decode)
decode <= 1'b0;
else if(decode_en)
decode <= 1'b1;
end
// Diable the decoder to respond to further requests after receiving a request to decode,
always @(posedge oenable or negedge dec)
begin
if(!dec)
decode_flag <= 1'b0;
else
decode_flag <= 1'b1;
end
// Data from internal registers is available.
always @(negedge BCLK)
begin
if(decode_en)
decode_en <= 1'b0;
else if(oenable)
decode_en <= 1'b1;
end
// Generation of address and oenable signals to internal registers.
always@(posedge BCLK or negedge reset_n)
begin
if(!reset_n)
begin
ADDR_IR <= 8'h00;
oenable <= 1'b0;
source_ID <= 16'h0000;
data_flag <=1'b0;
end
else if(dec && !decode_flag) ///////////////
begin
ADDR_IR <= SOURCEID_; //address of IR for source ID value
oenable <= 1;
source_ID <= 16'h0000;
data_flag <= 1'b0;
end
else if(oenable)
begin
ADDR_IR <= 8'h00;
oenable <= 1'b0;
source_ID <= DATA_IR;
data_flag <= 1'b1;
end
end
// Checking of destination and broadcast address.
// Generation of error if there is a mismatch.
always @(data_flag or dest_error or dest_id or source_ID or d_error or reset_n or receive_or_transmit)
begin
if(!reset_n)
begin
dest_error <= 0;
broadcast <=0;
end
else if(!data_flag)
begin
dest_error <= 0;
broadcast <=0;
end
else if(data_flag)
begin
if(dest_id == 16'hffff)
begin
dest_error <= 0;
broadcast <= 1;
end
else if((source_ID != dest_id) && (dest_id != 16'hffff))
begin
dest_error <= 1;
broadcast <=0;
end
else
begin
dest_error<=0;
broadcast <=0;
end
end
else
begin
dest_error <= 0;
broadcast <=0;
end
decode_error = d_error | (~receive_or_transmit & dest_error); //receive_or_transmit = 0 for receive mode
end
endmodule