6502.org
http://forum.6502.org/

6523T in Verilog (general Verilog question, actually)
http://forum.6502.org/viewtopic.php?f=10&t=2894
Page 1 of 1

Author:  brain [ Sat Mar 08, 2014 4:44 am ]
Post subject:  6523T in Verilog (general Verilog question, actually)

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

Author:  ElEctric_EyE [ Sun Mar 09, 2014 12:10 am ]
Post subject:  Re: 6523T in Verilog (general Verilog question, actually)

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...

Author:  brain [ Sun Mar 09, 2014 11:09 pm ]
Post subject:  Re: 6523T in Verilog (general Verilog question, actually)

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

Author:  Rob Finch [ Sun Mar 09, 2014 11:23 pm ]
Post subject:  Re: 6523T in Verilog (general Verilog question, actually)

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.

Author:  brain [ Mon Mar 10, 2014 5:51 am ]
Post subject:  Re: 6523T in Verilog (general Verilog question, actually)

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

Page 1 of 1 All times are UTC
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/