6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu May 23, 2024 10:40 am

All times are UTC




Post new topic Reply to topic  [ 5 posts ] 
Author Message
PostPosted: Sat Mar 08, 2014 4:44 am 
Offline

Joined: Tue May 05, 2009 2:49 pm
Posts: 108
Someone sent me a note this week wanting to find a source for the MOS 6523T Tri Port Interface, and I felt after looking at the datasheet that I could just whip one up in Verilog.

And... I think I have, but along the way, I am stuck on a chunk of Verilog that I can't seem to get my arms around.

To create the design, I created 6 registers (3 output holding regs for the output data, and 3 ddr regs).

Code:
register                reg_port_a(r_w, reset, ce & (address == 0), data[7:0], rega_out);
register                reg_port_b(r_w, reset, ce & (address == 1), data[7:0], regb_out);
register                reg_port_c(r_w, reset, ce & (address == 2), data[7:0], regc_out);
register                reg_ddr_a(r_w, reset, ce & (address == 3), data[7:0], ddra);
register                reg_ddr_b(r_w, reset, ce & (address == 4), data[7:0], ddrb);
register                reg_ddr_c(r_w, reset, ce & (address == 5), data[7:0], ddrc);


Mux to handle the addressing:

Code:
mux8_1                   reg_mux(address[2:0],rega_in, regb_in , regc_in, ddra, ddrb, ddrc,0,0,reg_data);
assign data = (r_w & ce ? reg_data : 8'bz); // show values on read


and 3 io ports:

Code:
ioport                  ioport_a(ddra,porta, rega_out, rega_in);
ioport                  ioport_b(ddrb,portb, regb_out, regb_in);
ioport                  ioport_c(ddrc,portc, regc_out, regc_in);


It's this last part that I am struggling with. I got it to compile and the RTL looks right (need to test it, obviously), but the code is not generic like I want:

Code:
module ioport(ddr, io_port, d, q);

parameter WIDTH = 8 ;

input [WIDTH-1:0] ddr;        // data direction register
inout [WIDTH-1:0] io_port;     // external IO
input [WIDTH-1:0] d;            // data from IO pins to be read into memory
output [WIDTH-1:0] q;         // data from internal register to be placed on IO pins
reg [WIDTH-1:0] q;

integer i;

// also tried to put a generate/begin/for block here, but no dice.
assign io_port[0] = (ddr[0] ? d[0] : 'bz);  // if ddr is high, put data on output pin, else hi z
assign io_port[1] = (ddr[1] ? d[1] : 'bz);  // if ddr is high, put data on output pin, else hi z
assign io_port[2] = (ddr[2] ? d[2] : 'bz);  // if ddr is high, put data on output pin, else hi z
assign io_port[3] = (ddr[3] ? d[3] : 'bz);  // if ddr is high, put data on output pin, else hi z
assign io_port[4] = (ddr[4] ? d[4] : 'bz);  // if ddr is high, put data on output pin, else hi z
assign io_port[5] = (ddr[5] ? d[5] : 'bz);  // if ddr is high, put data on output pin, else hi z
assign io_port[6] = (ddr[6] ? d[6] : 'bz);  // if ddr is high, put data on output pin, else hi z
assign io_port[7] = (ddr[7] ? d[7] : 'bz);  // if ddr is high, put data on output pin, else hi z
      
always @*
  begin
    for (i = 0; i < WIDTH; i = i + 1)
      begin
         // below is what I want to do
         //io_port[i] = (ddr[i] ? d[i] : 'bz);  // if ddr is high, put data on output pin, else hi z
         q[i] <= (!ddr[i] ? io_port[i] : 0);  // if ddr is low, put input on reg pin, else 0
      end
  end 
endmodule


See that horrid 8 line abomination. I know I am just missing the trick to this, but I have tried a few different solutions. generate/for gave errors on conditional logic, putting the assign in the main for block errors, and just putting a for in the beginning of the module errors out as well. I can't seem to find conditional logic generate statements or my googlefu is sufficiently weak tonight.

Help on this point would be appreciated, and I'm happy to put the resulting file up for anyone, it's nothing special. At present, it implements a 6523, but subsetting the bits will turn it into a 6523T (12 bits instead of 24)

Jim


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 09, 2014 12:10 am 
Offline

Joined: Mon Mar 02, 2009 7:27 pm
Posts: 3258
Location: NC, USA
I'm just curious...
So I gather the MOS6523 was typically a 40-pin device used in the Amiga. It had a 8-bit R/W databus from the cpu, and 3 8-bit I/O ports to different peripherals?

A data sheet link/attachment would be nice if you have one, so we can compare a truth table to your code. Just glancing at your code, you set actions based on individual bit settings, that looks wrong to me...

_________________
65Org16:https://github.com/ElEctric-EyE/verilog-6502


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 09, 2014 11:09 pm 
Offline

Joined: Tue May 05, 2009 2:49 pm
Posts: 108
http://www.zimmers.net/anonftp/pub/cbm/ ... index.html

Each pin of each IO port can be individually set to input or output. Otherwise, there is not much in the 6523

Jim


Top
 Profile  
Reply with quote  
PostPosted: Sun Mar 09, 2014 11:23 pm 
Offline
User avatar

Joined: Sun Dec 29, 2002 8:56 pm
Posts: 449
Location: Canada
Code:
assign io_port[0] = (ddr[0] ? d[0] : 'bz);  // if ddr is high, put data on output pin, else hi z
assign io_port[1] = (ddr[1] ? d[1] : 'bz);  // if ddr is high, put data on output pin, else hi z
assign io_port[2] = (ddr[2] ? d[2] : 'bz);  // if ddr is high, put data on output pin, else hi z
assign io_port[3] = (ddr[3] ? d[3] : 'bz);  // if ddr is high, put data on output pin, else hi z
assign io_port[4] = (ddr[4] ? d[4] : 'bz);  // if ddr is high, put data on output pin, else hi z
assign io_port[5] = (ddr[5] ? d[5] : 'bz);  // if ddr is high, put data on output pin, else hi z
assign io_port[6] = (ddr[6] ? d[6] : 'bz);  // if ddr is high, put data on output pin, else hi z
assign io_port[7] = (ddr[7] ? d[7] : 'bz);  // if ddr is high, put data on output pin, else hi z


I think you may be able to do something like:

Code:
assign io_port = ddr ? d : {{WIDTH-1}{1'bz}};
assign q = ddr ? 0 : io_port;


Verilog understands to do things a bit at a time when there are no bit indexes specified.

_________________
http://www.finitron.ca


Top
 Profile  
Reply with quote  
PostPosted: Mon Mar 10, 2014 5:51 am 
Offline

Joined: Tue May 05, 2009 2:49 pm
Posts: 108
Yes, indeed, that:

Code:
module ioport(ddr, io_port, d, q);

parameter WIDTH = 8 ;

input [WIDTH-1:0] ddr;        // data direction register
inout [WIDTH-1:0] io_port;     // external IO
input [WIDTH-1:0] d;            // data from IO pins to be read into memory
output [WIDTH-1:0] q;         // data from internal register to be placed on IO pins

assign io_port = ddr ? d : {{WIDTH-1}{1'bz}};
assign q = ddr ? 0 : io_port;

endmodule


appears to be the ticket.

Thanks. That looks like it worked. I need to wire up a bit and test it on a Plus/4

Jim


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: