So I have a simple design to replicate some of the logic on one (old) computer bus such that it looks like some signals (that were removed on a later revision of the bus) are still there. It's not particularly long...
`timescale 1ns / 1ps
module xlbus
(
input clk, // Clock from STM32 MCO @ 108MHz
input rst_n, // Reset (active low)
input [7:0] addr, // Upper 8 bits of address
input rd4, // High when right cartridge selected
input rd5, // High when left cartridge selected
input selftestSel, // High when self-test mode enabled
input basicSel, // High when BASIC ROM enabled
input mpSel, // High when MathPak is disabled
input osSel, // High when OS is enabled
output reg mpd, // MathPakDisable signal
output reg extenb // External-access enable signal
);
// Cartridge inserted into "left" slot, or built-in BASIC enabled
// ($D301, bit 1 == 0). rd5 is active-high
wire cartL = (rd5 | basicSel) & (addr >= 8'ha0) & (addr <= 8'hbf);
// Cartridge inserted into "right" slot. rd4 is active-high
wire cartR = rd4 & (addr >= 8'h80) & (addr <= 8'h9f);
// Self-Test mode enabled ($D301, bit 7 == 1)
wire osTest = selftestSel & (addr >= 8'h50) & (addr <= 8'h58);
// I am unaware of any way to turn these off, but provide osSel anyway...
wire rom1 = osSel & (addr >= 8'hc0) & (addr <= 8'hcf);
wire rom2 = osSel & (addr >= 8'he0) & (addr <= 8'hff);
// We need to assert /MPD very early in the bus cycle, so follow a
// register-based approach rather than having to monitor each bus-
// event. If the STM is currently asserting "mpSel" then any access
// to the math-pak area will send a timely assert, without needing
// processing within 10's of nanoseconds. We can arrange for that to
// be set first by the driver s/w, before any accesses are required.
// (and unset later, obviously)
wire mathpak = mpSel & (addr >= 8'hd0) & (addr <= 8'hd7);
always @ (posedge clk or negedge rst_n)
if (rst_n == 1'b0)
begin
extenb <= 1'b1;
mpd <= 1'b1;
end
else
begin
extenb <= !(cartL | cartR | osTest | rom1 | rom2);
mpd <= !mathpak;
end
/*
assign extenb = !(cartL | cartR | osTest | rom1 | rom2);
assign mpd = !mathpak;
*/
endmodule
This all seems pretty well-behaved at first glance...
But Quartus is unhappy with me, telling me the output paths are unconstrained.
I can believe that - of the various black-magic rites associated with FPGA's/CPLD's, timing constraints was not one I ever really grocked. All I told it this time around was that there was a 100MHz clock in the .SDC file ....
create_clock -name "clk100" -period 10.000ns [get_ports {clk}] -waveform {0.000 5.000}
# Automatically constrain PLL and other generated clocks
derive_pll_clocks -create_base_clocks
So I guess what I'm asking is:
- What do I need to do to make Quartus happy with me ?
- How do I figure out if it'll meet timing ?
Regarding that last, I haven't really played with CPLDs before, but I *thought* the MAX7000A (well, actually the Microchip ATF1052AS) timing was specified in terms of input-signal-to-output-signal (rather than gate-to-gate) so it *all* ought to fit into the 20ns (or 15ns or 7.5ns or whatever) budget, right ? In which case, do I even care about timing if it "compiles" ?
As usual, any and all help gratefully received
Aside, Quartus 13.0sp1 runs really nicely under Wine on my Arm-based Mac... Which is pretty impressive from the Wine folks...