Connected a UART. Communicating via a 3.3V FTDI USB-serial port to my linux box.
I am using the UART from Xilinx, the one that comes with Picoblaze. I wrapped it into a module for easy interfacing (I will keep updating here):
Code:
/******************************************************************************
UART - wrapper around the Xilinx Picoblaze uart.
Files required:
bbfifo_16x8.v
kcuart_rx.v
kcuart_tx.v
uart_rx.v
uart-tx.v
To connect to arlet's 6502 core, I decode an 8-byte memory location (with SEL).
Base address is the status register when read. Base+1 is the data register,
which can be read or written. In the future I may add other registers.
******************************************************************************/
module mUART(
input CLK
, input [2:0] addr
, input SEL
, input WE
, input [7:0] DI
, output reg [7:0] DO
// interface to hardware
, output TX
, input RX
);
//-----------------------------------------------------------------------------
// The UART requires pulses at the rate of BAUD * 16. At 30MHz, use a 16-bit
// shift register with a single bit on...This provides 115200 * 16 (close to)
wire baud_x16;
SRL16 #(.INIT(1)) baudshifter1 (baud_x16,1,1,1,1,CLK,baud_x16);
//
wire tx_full;
wire tx_half_full;
wire rx_full;
wire rx_half_full;
wire rx_data_present;
wire [7:0] rx_data;
wire do_tx;
wire do_rx;
//-----------------------------------------------------------------------------
// uart tx
//-----------------------------------------------------------------------------
uart_tx utx(
DI, //data to send out
do_tx,
0, //reset buffer
baud_x16, // baud rate x 16 pulses
TX, // output pin
tx_full,
tx_half_full,
CLK);
//-----------------------------------------------------------------------------
// uart rx
//-----------------------------------------------------------------------------
uart_rx urx(
RX, //input pin
rx_data[7:0], //input data
do_rx, //when strobed, consider read done
0, //rx reset buffer
baud_x16, //baud
rx_data_present,
rx_full,
rx_half_full,
CLK);
//-----------------------------------------------------------------------------
// mux for the output value: even=status odd=data
always @ (posedge CLK)
if(SEL & ~WE)
if(addr[0])
DO <= rx_data[7:0];
else
DO <= {rx_data_present, rx_full, rx_half_full,2'b00, tx_full, tx_half_full};
else
DO <= 8'h00;
assign do_tx = WE & SEL;
assign do_rx = ~WE & SEL & addr[0]; //any odd address acks read
endmodule
And here is (not the most elegant) 6502 code to send and receive characters, blocking:
Code:
UART_BASE equ $C008 ;C008-C00F dedicated to the UART
UART_STATUS equ UART_BASE
UART_DATA equ UART_BASE+1
emit:
tax ;move character to x for now
lda UART_STATUS
and #$02 ;buffer full?
bne emit ;yes, keep trying
stx UART_DATA
txa
rts
key:
lda UART_STATUS
and #$40 ;rx data present?
beq key ;no, keep trying
lda UART_DATA
rts
Attachment:
6502play.c.term.jpg [ 46.71 KiB | Viewed 2139 times ]
With good looking fonts, too!
I still have to find out the SRAM/BRAM blink rate problem, but now I can write a debugger...