Help: not quite working correctly.

P

Prime

Guest
Hi,

I am trying to teach myself verilog, and have run into the following problem.
I have a Xilinx XC9536 linked up to the expansion connector of an old
(6809 based) micro, so that I can use it as an IO buffer. I have connected
the relevant bus signals to the CPLD, and have two sets of pins configured
as porta output and portb input.

I have the output port working fine, when I write a value to the port, it is
appears on the output port pins (I have some leds connected to these), however
reading from the input port I cannot get to work.

I have included the code below, I'm sure it's something simple,
but my beginner's eyes can't spot it :)

// Test module for reading and writing ports within a CPLD.
// Host system is a motorola 6809 based machine.

module DragonTest(halt,addr,rw,reset,e,p2,
porta,portb,data,
firq,nmi);

input [0:4]addr; // Bottom 5 address lines
input rw; // R/W line
input reset; // Reset line
input e; // E Clock
input p2; // P2 active low at addresses $FF40-$FF5F

inout [0:7]porta; // Port A
inout [0:5]portb; // Port B (only 6 bits wide)
inout [0:7]data; // CPU data bus

output firq; // FIRQ inturrupt line
output nmi; // NMI Inturrupt line
output halt; // Processor HALT line

reg [0:7] porta_latch; // Port A output latch
reg [0:5] portb_latch; // Port B input latch
reg [0:7] data_out; // Data bus output latch

assign porta = porta_latch; // Always output latched value on port A

// Force inturrupts & halt into hi-z as we currently don't use them
assign nmi = 1'bz;
assign firq = 1'bz;
assign halt = 1'bz;

// Enable signal,
wire enable1;

// Enable ourselves between $FF50-$FF5F
assign enable1 = !p2 & addr[4] & e;
assign out_enable = enable1 & rw;

// Only output data on bus, if we are selected, and processor is reading
// (R/W=high).
assign data = out_enable ? data_out : 8'bzzzzzzzz;

always @(posedge enable1 or negedge reset)
begin
// Reset latches to known sensible values.
if(reset==0)
begin
porta_latch = 8'b00000000;
portb_latch = 8'b100100;
data_out = 8'bzzzzzzzz;
end
else
begin
if(rw==1) // RW=1, so processot reading
begin
portb_latch=portb; // Latch data in *****
data_out={0,0,portb_latch}; // Latch onto data bus.
end
else // RW=0, so processor writing.
begin
porta_latch=data; // latch data out to port A
end
end
end
endmodule


**** If I comment out this line, and read the port I get back the value, of
portb_latch setup by the reset clause, however I never seem to be able to
read the values from the chip pins.

Cheers.

Phill.
 
"Prime" <afra@666aurigae.demon.co.uk> wrote in message
news:Xns96D0D84075B90primeaurigae@158.152.254.254...
Hi,

I am trying to teach myself verilog, and have run into the following
problem.
I have a Xilinx XC9536 linked up to the expansion connector of an old
(6809 based) micro, so that I can use it as an IO buffer. I have connected
the relevant bus signals to the CPLD, and have two sets of pins configured
as porta output and portb input.

I have the output port working fine, when I write a value to the port, it
is
appears on the output port pins (I have some leds connected to these),
however
reading from the input port I cannot get to work.
<snip>

I've reformatted your code to my liking (including Verilog2001 port
conventions). The use of blocking operators (=) is replaced with
non-blocking operators (<=) which are preferred in sequential logic design
and provide the "everything at once" nature of registers we hardware guys
are so familiar with. I've changed the clock from a "gated clock" (we don't
like combinatorial results driving our clocks) to a simply clocked block
with appropriate enables. Note that undimensioned integers are 32 bits wide
({0,0} is 64'b0).

It looks like the code should work as long as you expect the data to read
back only during the positive phase of the clock "e" and not at the next (or
current!) rising edge. Since the "enable1" was a gated clock, I removed the
"& e" to get a real enable (now found with the assignments) and included it
in the out_enable to keep the original logic for *that* signal. Is the
positive-phase-only really waht you wanted for that drive?

Because I changed to non-blocking operators, the portb_latch value is
changed on the rising edge of e when the enable conditions are satisfied,
the data_out receives the previous value of portb_latch, and the data bus
only provided the previous value of data_out when the enable and "e" clock
were both asserted, probably on both sides of the single clock period.

What do you *want* in the timing for data relative to the read value for the
raw portb inputs to your chip?


module
DragonTest
( output halt // Processor HALT line
, input [0:4] addr // Bottom 5 address lines
, input rw // R/W line
, input reset // Reset line
, input e // E Clock
, input p2 // P2 active low at addresses $FF40-$FF5F
, inout [0:7] porta // Port A
, inout [0:5] portb // Port B (only 6 bits wide)
, inout [0:7] data // CPU data bus
, output firq // FIRQ inturrupt line
, output nmi // NMI Inturrupt line
);


reg [0:7] porta_latch; // Port A output latch
reg [0:5] portb_latch; // Port B input latch
reg [0:7] data_out; // Data bus output latch

assign porta = porta_latch; // Always output latched value on port A

// Force inturrupts & halt into hi-z as we currently don't use them
assign nmi = 1'bz;
assign firq = 1'bz;
assign halt = 1'bz;

// Enable ourselves between $FF50-$FF5F
wire enable1 = !p2 & addr[4];
wire out_enable = enable1 & e & rw;

// Only output data on bus, if we are selected, and processor is reading
// (R/W=high).
assign data = out_enable ? data_out : 8'hzz;

always @(posedge e or negedge reset)
if( ~reset ) // Reset latches to known sensible values.
begin
porta_latch <= 8'h00;
portb_latch <= 6'b24;
data_out <= 8'h00;
end
else if( enable1 )
begin
if( rw ) // read
begin
portb_latch <= portb; // Latch data in *****
data_out <= {2'b00,portb_latch}; // Latch onto data bus.
end
else // write
porta_latch <= data; // latch data out to port A
end

endmodule
 

Welcome to EDABoard.com

Sponsor

Back
Top