Another Home-Brew - Z180

General "chat", not necessarily MTX related
User avatar
Dave
Posts: 1280
Joined: 11 Aug 2012 18:16
Contact:

Re: Another Home-Brew - Z180

Post by Dave »

Of course, there is a more expensive, but usually reliable option . . . .

Get it made in China :D

If you are confident of the design, or at least, confident that minimal rework (using the Memotech patch wire technique :)) might be required, then you could just go for it?

Advantages
Not having to use suspect old photo resist PCBs
Not having to mess with horrible chemicals
Reduce uncertainty

Disadvantages
Time - probably a couple of weeks for budget delivery
Cost - 5 x Eurocard size, about $35 + $10 delivery

If it works, you could offset the cost by selling the extra boards to “the usual suspects” 8-)

Regards
Dave
Bill B
Posts: 593
Joined: 26 Jan 2014 16:31

Re: Another Home-Brew - Z180

Post by Bill B »

But that is cheating :shock:

It still frustrates me that I have to use proprietary tools to design and program the CPLDs. In the old days I wrote my own assembler and built my own EPROM eraser and programmer. Perhaps I should have done a discrete logic design.

In order to get the board made commercially I would have to do a fair amount of rework on the CAD design. For example I make the holes in all the pads small, to just provide a centre for the drilling. If made commercially I would need to increase these to match the actual pin sizes. I'm not sure what else would need cleaning up, for my purposes I am only interested in the two copper layers.

Also the layout was dictated by what I could realistically achieve with home etching. It could almost certainly be improved for a commercially made board, see my earlier post.

Time is not an issue, with other commitments it will probably take me at least as long to develop, etch and drill (particularly drill) a board myself.
Bill B
Posts: 593
Joined: 26 Jan 2014 16:31

Re: Another Home-Brew - Z180

Post by Bill B »

I need to get some more materials before I can have another go at etching a board. However, assuming that I eventually succeed with that, attached is a preliminary design for the second board to contain:
  • SD Card interface
  • Real Time Clock
  • Floating Point Unit
This board layout is looking a bit empty. I will have to consider what else I might include.
Attachments
Z180_EC_v3_UTIL_PCB.pdf
PCB Layout for second board
(46.97 KiB) Downloaded 420 times
Z180_EC_v3_UTIL_Circuit.pdf
Circuit for second board
(80.83 KiB) Downloaded 347 times
Bill B
Posts: 593
Joined: 26 Jan 2014 16:31

Re: Another Home-Brew - Z180

Post by Bill B »

It appears that my proposed SD Card interface is pushing the limits of the small CPLD I am planning to use.

My initial VHDL was:

Code: Select all

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity  Z180_EC_Util_CPLD is
  port (
    data : inout std_logic_vector(7 downto 0);
    addr : in std_logic_vector(7 downto 0);
    rd, wr, iorq, phi, reset : in std_logic;
    cs_fpu, rst_fpu, fpu_clk, cs_rtc, as_rtc : out std_logic;
    sd_mosi : out std_logic;
	sd_clk, sd_cs, sd_pull : buffer std_logic;
    sd_miso : in std_logic
    );
end Z180_EC_Util_CPLD;

architecture behaviour of Z180_EC_Util_CPLD is
  constant port_rtc_addr : std_logic_vector(7 downto 0) := X"42";
  constant port_rtc_data : std_logic_vector(7 downto 0) := X"43";
  constant port_fpu_data : std_logic_vector(7 downto 0) := X"44";
  constant port_fpu_rst : std_logic_vector(7 downto 0) := X"45";
  constant port_sd_data : std_logic_vector(7 downto 0) := X"46";
  constant port_sd_ctrl : std_logic_vector(7 downto 0) := X"47";
  signal fpu_cnt : std_logic_vector (2 downto 0);
  signal sel_sd_data : std_logic;
  signal sel_sd_ctrl : std_logic;
  signal sd_auto : std_logic := '0';
  signal sd_once : std_logic := '0';
  signal sd_arm : std_logic := '0';
  signal sd_run : std_logic := '0';
  signal sd_out : std_logic_vector(7 downto 0);
  signal sd_in : std_logic_vector(8 downto 0);
begin
  -- IO Decoding
  cs_rtc <= iorq when ( addr = port_rtc_data ) else '1';
  as_rtc <= ( iorq nor wr ) when ( addr = port_rtc_addr ) else '0';
  cs_fpu <= iorq when ( addr = port_fpu_data ) else '1';
  process (iorq, wr, addr, data)
  begin
    if ( ( iorq = '0' ) and ( wr = '0' ) and ( addr = port_fpu_rst ) ) then
      rst_fpu <= data(0);
    end if;
  end process;
  -- FPU Clock
  process (phi)
  begin
    if ( falling_edge (phi) ) then
      fpu_cnt <= fpu_cnt + 1;
    end if;
  end process;
  fpu_clk <= fpu_cnt(2);
  -- SPI control register
  sel_sd_data <= iorq when ( addr = port_sd_data ) else '1';
  sel_sd_ctrl <= iorq when ( addr = port_sd_ctrl ) else '1';
  process (wr, sel_sd_ctrl, data, reset)
  begin
    if ( reset = '0' ) then
      sd_cs <= '0';
      sd_pull <= '0';
      sd_auto <= '0';
    elsif ( ( sel_sd_ctrl = '1' )  and ( wr = '0' ) ) then
      sd_cs <= data(0);
      sd_pull <= data(1);
      sd_auto <= data(2);
    end if;
  end process;
  -- Arm SPI transfer: Always after a write (sd_once) or conditional (sd_auto) after a read
  sd_clk <= sd_run and phi;
  process (sel_sd_data, wr, sd_clk, reset)
  begin
    if ( ( sd_clk = '1' ) or ( reset = '0' ) ) then
      sd_once <= '0';
    elsif ( ( sel_sd_data = '0' ) and ( wr = '0' ) ) then
      sd_once <= '1';
    end if;
  end process;
  process (sel_sd_data, sd_clk, reset)
  begin
	if ( ( sd_clk = '1' ) or ( reset = '0' ) ) then
	   sd_arm <= '0';
    elsif ( rising_edge (sel_sd_data) ) then
      sd_arm <= sd_once or sd_auto;
	end if;
  end process;
  -- Run byte transfer from next low clock
  process (phi, sd_arm, sd_in, reset)
  begin
    if ( reset = '0' ) then
	   sd_run <= '0';
    elsif ( falling_edge (phi) ) then
      sd_run <= sd_arm or ( not sd_in(8) );
	 end if;
  end process;
  -- Output bits on falling clock edge
  process (sd_clk, sel_sd_data, wr, data)
  begin
    if ( ( sel_sd_data = '0' ) and ( wr = '0' ) ) then
      sd_out <= data;
    elsif ( falling_edge (sd_clk) ) then
      sd_out(6 downto 0) <= sd_out(7 downto 1);
      sd_out(7) <= '1';
    end if;
  end process;
  sd_mosi <= sd_out(0);
  -- Input bits on rising clock edge
  process (sd_clk, sd_arm, sd_run, sd_miso)
  begin
    if ( ( sd_arm = '1' ) and ( sd_run = '0' ) ) then
      -- Transfer will stop when '1' is shifted into high bit.
      sd_in <= "000000001";
    elsif ( rising_edge (sd_clk) ) then
      sd_in(8 downto 1) <= sd_in (7 downto 0);
      sd_in(0) <= sd_miso;
    end if;
  end process;
  -- Read SPI data and control registers
  data <= sd_in(7 downto 0) when ( ( rd = '0' ) and ( sel_sd_data = '0' ) ) else
          ( 0 => sd_cs, 1 => sd_pull, 2 => sd_auto, 3 => sd_once,
            4 => sd_arm, 5 => sd_run, 6 => '0', 7 => sd_miso )
          when ( ( rd = '0' ) and ( sel_sd_ctrl = '0' ) ) else
          ( others => 'Z' );
end behaviour;
However, attempting to compile that fails with:

Code: Select all

Fitter Status	Failed
Quartus II 64-Bit Version	13.0.1 Build 232 06/12/2013 SP 1 SJ Web Edition
Revision Name	Z180_EC_Util_CPLD
Top-level Entity Name	Z180_EC_Util_CPLD
Family	MAX7000S
Device	EPM7032SLC44-10
Timing Models	Final
Total macrocells	42 / 32 ( 131 % )
Total pins	32 / 36 ( 89 % )
Overcommitted by 31% :( The obvious first thing to try removing is the divider for the FPU clock. That can be replaced by a single external divide by 8 counter. That gives:

Code: Select all

Flow Status	Flow Failed
:
Total macrocells	39 / 32 ( 122 % )
Total pins	31 / 36 ( 86 % )
As is perhaps expected, removing a 3-bit counter saves 3 macrocells. Not enough :(

The above VHDL includes the ability to read back a number of internal status bits. The only one of these which is essential is the state of the MISO pin. So, simplifying this bit of the VHDL to:

Code: Select all

  data <= sd_in(7 downto 0) when ( ( rd = '0' ) and ( sel_sd_data = '0' ) ) else
          ( 7 => sd_miso, others => 'Z' ) when ( ( rd = '0' ) and ( sel_sd_ctrl = '0' ) ) else
          ( others => 'Z' );
Gets closer:

Code: Select all

Fitter Status	Failed - Sun Oct 06 09:51:43 2019
:
Total macrocells	32 / 32 ( 100 % )
Total pins	34 / 36 ( 94 % )

Error (163105): Cannot route source node "addr[3]" of type max_io to destination node "sd_out[3]" of type max_mcell
Just enough macrocells, but it appears that I cannot order the pins in the way I intended :( After some experimentation with the pin assignments:

Code: Select all

Fitter Status	Successful
:
Total macrocells	32 / 32 ( 100 % )
Total pins	34 / 36 ( 94 % )

Pin Name/Usage               : Location  : Dir.   : I/O Standard      : Voltage : I/O Bank  : User Assignment
-------------------------------------------------------------------------------------------------------------
reset                        : 1         : input  : TTL               :         :           : Y              
iorq                         : 2         : input  : TTL               :         :           : Y              
VCC                          : 3         : power  :                   :         :           :                
data[0]                      : 4         : bidir  : TTL               :         :           : Y              
data[1]                      : 5         : bidir  : TTL               :         :           : Y              
data[2]                      : 6         : bidir  : TTL               :         :           : Y              
TDI                          : 7         : input  : TTL               :         :           : N              
data[3]                      : 8         : bidir  : TTL               :         :           : Y              
data[4]                      : 9         : bidir  : TTL               :         :           : Y              
GND                          : 10        : gnd    :                   :         :           :                
data[5]                      : 11        : bidir  : TTL               :         :           : Y              
data[6]                      : 12        : bidir  : TTL               :         :           : Y              
TMS                          : 13        : input  : TTL               :         :           : N              
data[7]                      : 14        : bidir  : TTL               :         :           : Y              
VCC                          : 15        : power  :                   :         :           :                
sd_cs                        : 16        : output : TTL               :         :           : Y              
sd_clk                       : 17        : output : TTL               :         :           : Y              
sd_mosi                      : 18        : output : TTL               :         :           : Y              
RESERVED                     : 19        :        :                   :         :           :                
sd_pull                      : 20        : output : TTL               :         :           : Y              
rst_fpu                      : 21        : output : TTL               :         :           : Y              
GND                          : 22        : gnd    :                   :         :           :                
VCC                          : 23        : power  :                   :         :           :                
addr[0]                      : 24        : input  : TTL               :         :           : Y              
addr[1]                      : 25        : input  : TTL               :         :           : Y              
addr[2]                      : 26        : input  : TTL               :         :           : Y              
addr[3]                      : 27        : input  : TTL               :         :           : Y              
addr[4]                      : 28        : input  : TTL               :         :           : Y              
addr[5]                      : 29        : input  : TTL               :         :           : Y              
GND                          : 30        : gnd    :                   :         :           :                
addr[6]                      : 31        : input  : TTL               :         :           : Y              
TCK                          : 32        : input  : TTL               :         :           : N              
addr[7]                      : 33        : input  : TTL               :         :           : Y              
sd_miso                      : 34        : input  : TTL               :         :           : Y              
VCC                          : 35        : power  :                   :         :           :                
RESERVED                     : 36        :        :                   :         :           :                
cs_fpu                       : 37        : output : TTL               :         :           : Y              
TDO                          : 38        : output : TTL               :         :           : N              
as_rtc                       : 39        : output : TTL               :         :           : Y              
cs_rtc                       : 40        : output : TTL               :         :           : Y              
wr                           : 41        : input  : TTL               :         :           : Y              
GND                          : 42        : gnd    :                   :         :           :                
phi                          : 43        : input  : TTL               :         :           : Y              
rd                           : 44        : input  : TTL               :         :           : Y              
Success :D

It will be necessary to redo the board design to include a divider chip for the FPU clock, and the revised pin ordering.

The lack of remaining capacity complicates adding anything else to this board. Seperate I/O decoding will probably be required. Of course it would be possible to replace the EPM7032, by a EPM7128, but that seems excessive.

Any comments or sugestions as to how the VHDL or the pin asignments might be improved most welcome.
User avatar
Dave
Posts: 1280
Joined: 11 Aug 2012 18:16
Contact:

Re: Another Home-Brew - Z180

Post by Dave »

Hi Bill,

As you need to redo the board design anyway, have you tried letting the fitter freely allocate the pins? I think that will result in the most efficient logic solution.

The EPM7064 could be used too

Regards
Dave
Martin A
Posts: 799
Joined: 09 Nov 2013 21:03

Re: Another Home-Brew - Z180

Post by Martin A »

The EPM7064 might be obsolete, but the PLCC44 version of the ATF1504 is still in production.

So you could compile for the EPM7064, and run the output through POF2JED for programming the microchip part. (Quartus II being lightyears ahead of WinCUPL in the free development software world!)

The downside is the ATF15xx devices need a different programmer.
The upside is probably no board revision needed and another 20 or so macrocells if required.

I did a compile for the 7064 and that said inferred 5 latches, would it be possible to re-factor the VHDL to get rid of those ??
Bill B
Posts: 593
Joined: 26 Jan 2014 16:31

Re: Another Home-Brew - Z180

Post by Bill B »

Martin,

I think all the latches are fundamental to the design, although if anyone can come up with something better I would be interested.

Dave,

I have EPM7032 and EPM7128 chips from Lez. Also a USBBlaster clone (although I haven't tried that yet). Anything else I would have to buy. I could, but better the chips in hand.

I haven't tried free pin allocation with this design. However when I did that for the CPU CPLD the pins were in scrambled order, which would have been a nightmare to route on the board.

Edit: Also the EPM7032 only has two "Logic Array Blocks" (LAB). As best as I can tell, it only matters which LAB a signal is connected to, not which pin within the LAB is used. Therefore in order to simplify the board routing, I prefer to specify the pin order on the LAB.
Bill B
Posts: 593
Joined: 26 Jan 2014 16:31

Re: Another Home-Brew - Z180

Post by Bill B »

Following on from Martin's comment about re-factoring the VHDL, I have attempted to draw out the SD Card interface as a circuit diagram.
Attachments
SD_Card_Interface.pdf
(65.63 KiB) Downloaded 407 times
Martin A
Posts: 799
Joined: 09 Nov 2013 21:03

Re: Another Home-Brew - Z180

Post by Martin A »

Have you though about hooking up the Propeller 80 column display you designed for CFX-II as one of the I/O devices?

That gives a proven design using minimal external resources. Especially if you only use 80 column mode. That should make getting a diagnostic output up pretty straightforward.

It's fast enough to keep up with A Z80, that does 1 I/O wait state, at 9.8mhz. So with 3 or 4 I/O wait states programmed the Z180 should be OK too. Alternatively flipping the clock multiplier bits also works for slow I/O.
Bill B
Posts: 593
Joined: 26 Jan 2014 16:31

Re: Another Home-Brew - Z180

Post by Bill B »

Martin,

My Z180 project has got stalled a bit, delayed by software distractions from Memofest and otherwise. I hope to get back to it after Christmas.

However, I am certainly considering making use of a variant of my Propeller 80 column display. As per an earlier post, my peripherals board is currently sparsely populated. I think there is just room to fit the Propeller chip and associated components. Because of the higher bus speed I want to use proper level converters rather than resistors, which is a bit of a stretch space wise.
Post Reply