• Please review our updated Terms and Rules here

Fixing things ..

GilesGoat

Experienced Member
Joined
Dec 11, 2010
Messages
138
Location
Wales
I had a little bit of a play with the thing ..

"amazing" how many silly little logic bugs you can make when you think a thing and you do another ..

Ok so after some test with the VHDL simulator ( ModelSIM, evaluation ) turns out a couple of signals had the wrong polarity, another wasn't totally correct, another was a simulator mistake ..

The "working UART" should ( still testing a few more things ) as that :

Code:
entity SPIUart is
	Port ( sckl : in STD_LOGIC;
			 reset : in STD_LOGIC;
			 uart_write : in STD_LOGIC; -- '0' when it's a write to the uart TX register
			 uart_read : in STD_LOGIC; -- '0' when it's a read to Status or RX register
			 data : inout STD_LOGIC_VECTOR (7 downto 0); -- input/output data for the SPI
--			 ras : in STD_LOGIC;
			 cas : in STD_LOGIC;
			 cpuclk : in STD_LOGIC; -- cpu clock in microcycle mode
			 ioreg :  in STD_LOGIC_VECTOR (1 downto 0); -- DAL2, DAL1
			 pi : in STD_LOGIC;
			 si : in STD_LOGIC; -- serial IN
			 so : out STD_LOGIC; -- serial OUT
			 ss : out STD_LOGIC;
			 ready : out STD_LOGIC;
			 scout : out STD_LOGIC -- serial clock out
			 );
end SPIUart;

architecture Behavioral of SPIUart is

signal tmp : STD_LOGIC_VECTOR (7 downto 0);
signal tmp1 : STD_LOGIC_VECTOR (7 downto 0);
signal tmp2 : STD_LOGIC_VECTOR (7 downto 0);

signal l_si : STD_LOGIC; -- latched si
signal latch_data : STD_LOGIC; -- means data is valid to be used
signal output_data : STD_LOGIC; -- means data can be put on the bus

signal shreg : STD_LOGIC_VECTOR (15 downto 0); -- the 16 bits shift register
signal cnt : STD_LOGIC_VECTOR (4 downto 0); -- 5 bits counter

signal ready_enable : STD_LOGIC; -- when '0' the ready line can be pulsed
signal counter_reload : std_logic; -- when '0' the counter can be reloaded
signal notzerocount : std_logic; -- '0' when the counter is 0

begin

latch_data <= pi or uart_write; -- at the rising edge of PI on a WRITE, data is valid

output_data <= cas or uart_read; -- when CAS is LOW during a READ we can put data out

-- here we decide what to put in the "control byte" of the SPI uart

tmp1 <= "01000000" when ioreg = "00" else -- read  RCSR  ( read conf )
		  "00000000" when ioreg = "01" else -- read  RBUF  ( read RX buf )
		  "01000000" when ioreg = "10" else -- read  XCSR  ( read conf )
		  "10000000"; --when ioreg = "11"; -- write TXBUF ( write data )

-- here we decide what to put in as data on the bus when you read this thing

tmp2 <= shreg(15)&"XXXXXXX" when ioreg = "00" else -- RX status
		  shreg(7 downto 0)   when ioreg = "01" else -- RX data 
		  shreg(14)&"XXXXXXX" when ioreg = "10" else -- TX status
		  "XXXXXXXX"; -- don't care is never going to happen

notzerocount <= '0' when ( cnt /= 0 ) else '1';

ready_enable <= notzerocount or ( uart_read and uart_write ); -- this is when we can start delaying things
ready <= not (ready_enable) and cpuclk; -- gated by that 
counter_reload <= (uart_read and uart_write) or pi or cas; 

SPI_LATCH_INDATA: process ( latch_data, reset )
begin
   if ( reset = '0' or tmp1(7) = '0' ) then -- we have to be sure is all "00000000"
	    tmp <= ( others => '0' );
   elsif ( latch_data'event and latch_data = '1') then
		 tmp <= data;
	end if;
end process;

-- SI is always sample at any raising clock of sckl, so simple

SPI_SAMPLE_SI: process ( sckl )
begin
   if ( sckl'event and sckl = '1') then
		l_si <= si;
	end if;
end process;


SPI_SERIALIZE: process ( reset,counter_reload,sckl, notzerocount )

 begin

   if (reset = '0') then
	 cnt <= "00000";
	elsif (counter_reload = '0') then -- set counter to 16
    cnt <= "10000";
	 shreg <= tmp1 & tmp; -- control byte first, then data
   elsif ( sckl'event and sckl = '0') then -- this happens when spi_selected will return to '1'

	   -- serialize the data out
		if (notzerocount = '0') then
		    cnt <= cnt-1;
		    shreg <= shreg (14 downto 0) & l_si;
	   end if;
		
	end if;

 end process;
 
 so <= shreg(15) when notzerocount = '0' else '0';
 scout <= sckl when (notzerocount = '0' and counter_reload = '1') else '0';

 data <= tmp2 when output_data = '0' else "ZZZZZZZZ";

end Behavioral;

I hope I understood correctly that in "microcycle mode" you have one clock pulse every 3 .. 4 clock cycles and that pulse according to what I see in A-54 seems anyway to be 1/2 of the clock at X1/X0 so 200 ns, I need that clock for 2 different things that are :

- pulse the ready line
- supply the clock to the SPI port

I'd like to put up a screenshot of the simulation but it's a bit of a mess the "trial only" version of ModelSIM does not allow a nice export of the waveforms so I should take a snap of various screens and glue them togehter, I'll do it maybe when it's all finished.

I tried to install the free "PDFCreator" and kinda works but have to sort out a couple of thingies, then I'll put a link here to the PDF with the schematics.

Other than that, bad little news, tomorrow I must nip down the dentist to have a thoot fixed, I was considering trying to use some file and try something myself but after I've seen far too much advice about "DON'T DO IT" I booked for an appointment tomorrow ...

Oh well I think I was geeting close to my 6 months check anyway ...

I better not even think and start crying thinking there's quite proabaly a ( used ) PDP in my mouth already ...
 
Back
Top