//
// this module does programmed I/O. it is written to be able to drive both channels
// simultaneously, if desired. gulp.
//
// note: this module will NOT hold off on ddone! so if for some reason data comes in too
// fast, it'll be a problem (not sure what it will do....)
// this can be fixed easily by implementing an ack signal from the transmitter modules
//
module pio
(
// inputs
clock,
resetn,
mbreset,
dstrobe_in,
mbad_accept,
mbdata_in,
mbad,
ack,
// outputs
mbdata_out,
ddone_out,
output_channel,
send_boe,
send_eoe,
send_data,
inprogress,
state
);
input clock;
input resetn;
input mbreset;
input mbad_accept;
input dstrobe_in;
input[127:0] mbdata_in;
input[9:0] mbad;
input ack;
output[127:0] mbdata_out; reg[127:0] mbdata_out;
output ddone_out;
output output_channel; reg output_channel;
output send_boe; reg send_boe;
output send_eoe; reg send_eoe;
output send_data; reg send_data;
output[1:0] state;
output inprogress;
reg inprogress;
//
// channel 1 is set by bit0=0
// channel 2 is set by bit0=1
//
wire channel = mbad[0];
//
// boe is set by bit1=1
// eoe is set by bit2=1
// data is set by bit3=1
//
wire c_boe = mbad[1];
wire c_eoe = mbad[2];
wire c_data = mbad[3];
//
// latch the "strobes"
//
reg rmbad_accept;
reg rdstrobe_in;
always @ (posedge clock or negedge resetn)
if (~resetn) begin
rmbad_accept <= 0;
rdstrobe_in <= 0;
end
else begin
rmbad_accept <= mbad_accept;
rdstrobe_in <= dstrobe_in;
end
reg rm1, rm2, rm3;
reg rd1, rd2, rd3;
always @ (posedge clock) rm1 <= rmbad_accept;
always @ (posedge clock) rm2 <= rm1;
always @ (posedge clock) rm3 <= rm2;
always @ (posedge clock) rd1 <= rdstrobe_in;
always @ (posedge clock) rd2 <= rd1;
always @ (posedge clock) rd3 <= rd2;
//wire enable = rm3 & rd3;
wire enable = rmbad_accept & rdstrobe_in;
//
// the following line of code causes done to be issued as soon as
// everything is latched. if you want to change this to hold off
// on done until everything is stuff into the fifo's, you have to
// change this bit of code, and probably add an ack on the input
// (driven by whatever module watches this one)
//
//wire ddone_out = enable;
wire ddone_out = ack;
//
// state machine
//
reg[1:0] state, nextstate;
parameter[1:0] WAITD=0, SET_LINES=1, WAIT_ACK=2, WAIT_DSTROBE_GONE=3;
//
// now, latch on the enable signal
//
////always @ (posedge clock or negedge resetn)
always @ (negedge clock or negedge resetn)
if (~resetn) state <= WAITD;
else state <= nextstate;
always @ (enable or state or rdstrobe_in or ack)
case (state)
WAITD:
if (enable) nextstate = SET_LINES;
else nextstate = WAITD;
SET_LINES:
nextstate = WAIT_ACK;
WAIT_ACK:
if (ack) nextstate = WAIT_DSTROBE_GONE;
else nextstate = WAIT_ACK;
WAIT_DSTROBE_GONE:
if (~rdstrobe_in) nextstate = WAITD;
else nextstate = WAIT_DSTROBE_GONE;
default:
nextstate = WAITD;
endcase
//always @ (posedge clock or negedge resetn)
always @ (negedge clock or negedge resetn)
if (~resetn) begin
mbdata_out <= 0;
output_channel <= 0;
send_boe <= 0;
send_eoe <= 0;
send_data <= 0;
inprogress <= 0;
end
else case (state)
WAITD: begin
mbdata_out <= 0;
output_channel <= 0;
send_boe <= 0;
send_eoe <= 0;
send_data <= 0;
inprogress <= 0;
end
SET_LINES: begin
mbdata_out <= mbdata_in;
output_channel <= channel;
send_boe <= c_boe;
send_eoe <= c_eoe;
send_data <= c_data;
inprogress <= 1;
end
WAIT_DSTROBE_GONE: begin
send_boe <= 0;
send_eoe <= 0;
send_data <= 0;
end
default: begin
mbdata_out <= mbdata_out;
output_channel <= output_channel;
send_boe <= send_boe;
send_eoe <= send_eoe;
send_data <= send_data;
inprogress <= inprogress;
end
endcase
endmodule
This page: |
Created: | Sun Feb 4 08:56:54 2001 |
|
From: |
pio.v |