processor_interface.v
module processor_interface
(
clock, resetj,
up_pi_cs, up_pi_addr, up_pi_write, up_pi_read,
up_pi_data, pi_up_data, pi_up_ready, pi_up_int,
pi_tf_write, pi_tf_data, tf_pi_size, tf_pi_ready,
pi_rf_read, rf_pi_data, rf_pi_size, rf_pi_ready,
pi_ci_enable
);
// INTERFACE
input clock;
input resetj;
// PROCESSOR BUS
input up_pi_cs;
input [1:0] up_pi_addr;
input up_pi_write;
input up_pi_read;
input [15:0] up_pi_data;
output [15:0] pi_up_data;
output pi_up_ready;
output pi_up_int;
// TRANSMIT FIFO INTERFACE
output pi_tf_write;
output [15:0] pi_tf_data;
input [6:0] tf_pi_size;
input tf_pi_ready;
// RECEIVE FIFO INTERFACE
output pi_rf_read;
input [15:0] rf_pi_data;
input [6:0] rf_pi_size;
input rf_pi_ready;
// CHANNEL CONTROL BUS
output [1:0] pi_ci_enable;
// CONSTANTS
// REGISTER ADDRESSES
parameter COS_Data = 0;
parameter COS_Level = 1;
parameter COS_Transmit = 2;
parameter COS_Receive = 3;
// INTERNAL SIGNALS
// CHANNEL ENABLES. THE "Enable" FIELDS OF "Transmit" AND "Receive"
reg tf_enable;
reg rf_enable;
// CHANNEL INTERRUPT MASKS. THE "Mask" FIELDS OF "Transmit" AND "Receive"
reg tf_imask;
reg rf_imask;
// INTERRUPT WATERMARK LEVEL. THE "Level" REGISTER
reg [13:0] level;
// OUTPUT DATA BUS
reg [15:0] up_data;
// OUTPUT INTERRUPT. THE "Interrupt" FIELDS OF "Transmit" AND "Receive"
wire [1:0] up_int;
// IMPLEMENTATION
always@(posedge clock or negedge resetj)
// IF RESET ACTIVE, RESET REGISTERS
if (!resetj)
begin
tf_enable <= 1'b0;
rf_enable <= 1'b0;
tf_imask <= 1'b0;
rf_imask <= 1'b0;
level <= 14'b0;
end
// ELSE
else
begin
// IF THIS IS A WRITE OPERATION
if (up_pi_cs && up_pi_write)
begin
// SELECT THE REGISTER ASSOCIATED WITH THE ADDRESS
case (up_pi_addr)
// IF THE REGISTER IS "Level"
COS_Level:
// WRITE TO THE "Level" REGISTER
level <= up_pi_data[13:0];
// IF THE REGISTER IS "Transmit"
COS_Transmit:
// WRITE TO THE FIELDS OF "Transmit"
begin
tf_enable <= up_pi_data[15];
tf_imask <= up_pi_data[14];
end
// IF THE REGISTER IS "Receive"
COS_Receive:
// WRITE TO THE FIELDS OF "Receive"
begin
rf_enable <= up_pi_data[15];
rf_imask <= up_pi_data[14];
end
endcase
end
end
// SET THE OUTPUT DATA BUS FROM THE REGISTER SELECTED BY THE ADDRESS
always@(up_pi_addr or rf_pi_data or level or tf_enable or tf_imask or
rf_enable or rf_imask or up_int or tf_pi_size or rf_pi_size)
// SELECT THE REGISTER ASSOCIATED WITH THE ADDRESS
case (up_pi_addr)
// IF THE REGISTER IS "Data"
COS_Data:
// READ THE RECEIVE FIFO
up_data = rf_pi_data;
// IF THE REGISTER IS "Level"
COS_Level:
// READ THE "Level" REGISTER
up_data = level;
// IF THE REGISTER IS "Transmit"
COS_Transmit:
// ASSEMBLE THE FIELDS OF "Transmit"
up_data = {tf_enable, tf_imask, up_int[0], 6'b0, tf_pi_size};
// IF THE REGISTER IS "Receive"
COS_Receive:
// ASSEMBLE THE FIELDS OF "Receive"
up_data = {rf_enable, rf_imask, up_int[1], 6'b0, rf_pi_size};
endcase
assign pi_up_data = up_data;
// ASSERT THE READY SIGNAL PROVIDED THE CHIP IS SELECTED AND...
assign pi_up_ready = up_pi_cs && (
// EITHER THE REGISTER IS NOT "Data"
(up_pi_addr != COS_Data) ||
// OR THE APPROPRIATE FIFO IS READY
(tf_pi_ready && up_pi_write) ||
(rf_pi_ready && up_pi_read));
// ASSERT THE TRANSMIT/RECEIVE INTERRUPT IF NOT MASKED AND PROVIDED THE
// TRANSMIT/RECEIVE FIFO CONTAINS MORE FREE/DATA WORDS THAN THE WATERMARK
assign up_int = {rf_imask & (rf_pi_size>level), tf_imask & (tf_pi_size>level)};
// COMBINE THE INTERRUPT SIGNALS FOR OUTPUT TO THE PROCESSOR
assign pi_up_int = |up_int;
// SET THE TRANSMIT FIFO DATA TO EQUAL THE PROCESSOR INPUT DATA BUS
assign pi_tf_data = up_pi_data;
// ASSERT THE TRANSMIT/RECEIVE FIFO WRITE/READ SIGNAL IF THE CHIP IS
// SELECTED AND THE "Data" REGISTER IS BEING WRITTEN/READ
assign pi_tf_write = up_pi_cs && up_pi_addr == COS_Data && up_pi_write;
assign pi_rf_read = up_pi_cs && up_pi_addr == COS_Data && up_pi_read;
// ASSEMBLE THE CHANNEL CONTROL BUS
assign pi_ci_enable = {rf_enable, tf_enable};
endmodule
© Copyright 2000-2001 Adrian Lewis