diff --git a/examples/pal_reg.v b/examples/pal_reg.v index 2948a6904..170478814 100644 --- a/examples/pal_reg.v +++ b/examples/pal_reg.v @@ -20,16 +20,37 @@ /* * This example shows how to use Icarus Verilog to generate PLD output. * The design is intended to fit into a 22v10 in a PLCC package, with - * pin assignments locked down by design. + * pin assignments locked down by design. The command to compile this + * into a jedec file is; + * + * iverilog -tpal -fpart=generic-22v10-plcc -opal_reg.jed pal_reg.v + * + * The output file name (passed through the -o switch) can be + * any file you desire. If the compilation and fittin all succeed, the + * output file will be a JEDEC file that you can take to your favorite + * PROM programmer to program the part. + * + * This source demonstrates some important principles of synthesizing + * a design for a PLD, including how to specify synchronous logic, and + * how to assign signals to pins. The pin assignment in particular is + * part specific, and must be right for the fitting to succeed. */ + /* * The register module is an 8 bit register that copies the input to - * the output registers on the rising edge of the clk input. The output - * drivers are controled by a single active low output enable. + * the output registers on the rising edge of the clk input. The + * always statement creates a simple d-type flip-flop that is loaded + * on the rising edge of the clock. * - * This module contains all the logic of the device, but includes nothing - * that has anything to do with the real hardware. + * The output drivers are controlled by a single active low output + * enable. I used bufif0 devices in this example, but the exact same + * thing can be achived with a continuous assignment like so: + * + * assign out = oe? 8'hzz : Q; + * + * Many people prefer the expression form. It is true that it does + * seem to express the intent a bit more clearly. */ module register (out, val, clk, oe); @@ -53,6 +74,13 @@ endmodule * the device. We use this to lock down the pin assignments of the * synthesized result. The pin number assignments are for a 22v10 in * a PLCC package. + * + * Note that this module has no logic in it. It is a convention I use + * that I put all the functionality in a seperate module (seen above) + * and isolate the Icarus Verilog specific $attribute madness into a + * top-level module. The advantage of this style is that the entire + * module can be `ifdef'ed out when doing simulation and you don't + * need to worry that functionality will be affected. */ module pal; diff --git a/tgt-pal/fit_reg.c b/tgt-pal/fit_reg.c index 041aac4c3..29394dc43 100644 --- a/tgt-pal/fit_reg.c +++ b/tgt-pal/fit_reg.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) -#ident "$Id: fit_reg.c,v 1.1 2000/12/09 03:42:52 steve Exp $" +#ident "$Id: fit_reg.c,v 1.2 2000/12/09 05:40:42 steve Exp $" #endif # include @@ -25,6 +25,13 @@ # include # include "priv.h" +/* + * The fit_registers function scans all the scopes for flip-flop + * devices to be assigned to macrocells. First look to see if the + * device is connected to a PAD directly or through a bufif device. If + * not, then just pick a free macrocell and drop it there. + */ + static int scan_ff_q(ivl_lpm_ff_t ff, unsigned q); int fit_registers(ivl_scope_t scope) @@ -33,12 +40,17 @@ int fit_registers(ivl_scope_t scope) unsigned idx; unsigned lpms; + /* Scan child scopes first... */ rc = ivl_scope_children(scope, fit_registers); if (rc != 0) return rc; - lpms = ivl_scope_lpms(scope); + /* Scan the current scope for flip-flop devices. Pass the + devices we find to the scan_ff_q function to assign to a + macrocell. */ + + lpms = ivl_scope_lpms(scope); for (idx = 0 ; idx < lpms ; idx += 1) { ivl_lpm_t lpm = ivl_scope_lpm(scope, idx); ivl_lpm_ff_t ff; @@ -60,6 +72,10 @@ int fit_registers(ivl_scope_t scope) return 0; } +/* + * This is the part that actually assigns the single bit of a single + * flip-flop to a single macrocell. + */ int scan_ff_q(ivl_lpm_ff_t ff, unsigned q) { unsigned idx; @@ -93,7 +109,7 @@ int scan_ff_q(ivl_lpm_ff_t ff, unsigned q) } } - /* There is no poin connection, so try setting this to an + /* There is no pin connection, so try setting this to an unbound sop cell. We know that a sop is unbound if there are no enables, nexus or ff devices connected to it. */ @@ -120,6 +136,9 @@ int scan_ff_q(ivl_lpm_ff_t ff, unsigned q) /* * $Log: fit_reg.c,v $ + * Revision 1.2 2000/12/09 05:40:42 steve + * documentation... + * * Revision 1.1 2000/12/09 03:42:52 steve * Stuff registers into macrocells. * diff --git a/tgt-pal/imain.c b/tgt-pal/imain.c index 0f5afd267..1d35581e5 100644 --- a/tgt-pal/imain.c +++ b/tgt-pal/imain.c @@ -17,7 +17,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA */ #if !defined(WINNT) && !defined(macintosh) -#ident "$Id: imain.c,v 1.2 2000/12/09 03:42:52 steve Exp $" +#ident "$Id: imain.c,v 1.3 2000/12/09 05:40:42 steve Exp $" #endif /* @@ -67,8 +67,18 @@ int target_design(ivl_design_t des) key. Given the part type, try to open the pal description so that we can figure out the device. */ part = ivl_design_flag(des, "part"); - assert(part); + if (part == 0) { + fprintf(stderr, "error: part must be specified. Specify a\n"); + fprintf(stderr, " : type with the -fpart= option.\n"); + return -1; + } + pal = pal_alloc(part); + if (pal == 0) { + fprintf(stderr, "error: %s is not a valid part type.\n", part); + return -1; + } + assert(pal); pins = pal_pins(pal); @@ -132,6 +142,9 @@ DECLARE_CYGWIN_DLL(DllMain); /* * $Log: imain.c,v $ + * Revision 1.3 2000/12/09 05:40:42 steve + * documentation... + * * Revision 1.2 2000/12/09 03:42:52 steve * Stuff registers into macrocells. *