Added some stuff from modem and added formal

This commit is contained in:
2026-02-28 18:23:39 +01:00
parent fa641b1eab
commit cf7e03b9fe
55 changed files with 3717 additions and 31 deletions

View File

@@ -0,0 +1,49 @@
CAPI=2:
name: joppeb:primitive:clkgen:1.0
description: Parameterized clock generator wrapper
filesets:
wrapper:
files:
- clkgen.v
file_type: verilogSource
generic:
files:
- clkgen_generic_impl.v
file_type: verilogSource
spartan6:
files:
- clkgen_spartan6.v
file_type: verilogSource
targets:
default:
filesets:
- wrapper
- generic
- spartan6
toplevel: clkgen
parameters:
- CLK_IN_HZ
- CLKFX_DIVIDE
- CLKFX_MULTIPLY
- CLKDV_DIVIDE
parameters:
CLK_IN_HZ:
datatype: int
description: Input clock frequency in Hz
paramtype: vlogparam
CLKFX_DIVIDE:
datatype: int
description: DCM CLKFX divide value
paramtype: vlogparam
CLKFX_MULTIPLY:
datatype: int
description: DCM CLKFX multiply value
paramtype: vlogparam
CLKDV_DIVIDE:
datatype: real
description: DCM CLKDV divide value
paramtype: vlogparam

View File

@@ -0,0 +1,37 @@
`timescale 1ns/1ps
// =============================================================================
// Clock generator
// Stable public wrapper that selects the implementation.
// =============================================================================
module clkgen #(
parameter integer CLK_IN_HZ = 100000000,
parameter integer CLKFX_DIVIDE = 20,
parameter integer CLKFX_MULTIPLY = 3,
parameter real CLKDV_DIVIDE = 2.0
)(
input wire clk_in,
output wire clk_out
);
`ifdef FPGA_SPARTAN6
clkgen_spartan6_impl #(
.CLK_IN_HZ(CLK_IN_HZ),
.CLKFX_DIVIDE(CLKFX_DIVIDE),
.CLKFX_MULTIPLY(CLKFX_MULTIPLY),
.CLKDV_DIVIDE(CLKDV_DIVIDE)
) impl_i (
.clk_in(clk_in),
.clk_out(clk_out)
);
`else
clkgen_generic_impl #(
.CLK_IN_HZ(CLK_IN_HZ),
.CLKFX_DIVIDE(CLKFX_DIVIDE),
.CLKFX_MULTIPLY(CLKFX_MULTIPLY),
.CLKDV_DIVIDE(CLKDV_DIVIDE)
) impl_i (
.clk_in(clk_in),
.clk_out(clk_out)
);
`endif
endmodule

View File

@@ -0,0 +1,29 @@
`timescale 1ns/1ps
// =============================================================================
// Clock generator
// Generic behavioural model. This is intended for simulation only.
// =============================================================================
module clkgen_generic_impl #(
parameter integer CLK_IN_HZ = 100000000,
parameter integer CLKFX_DIVIDE = 20,
parameter integer CLKFX_MULTIPLY = 3,
parameter real CLKDV_DIVIDE = 2.0
)(
input wire clk_in,
output reg clk_out
);
real half_period_ns;
initial begin
clk_out = 1'b0;
half_period_ns = (500000000.0 * CLKFX_DIVIDE) / (CLK_IN_HZ * CLKFX_MULTIPLY);
// Start oscillation after the source clock becomes active.
@(posedge clk_in);
forever #(half_period_ns) clk_out = ~clk_out;
end
wire _unused_clkdv_divide;
assign _unused_clkdv_divide = (CLKDV_DIVIDE != 0.0);
endmodule

View File

@@ -0,0 +1,79 @@
`timescale 1ns/1ps
// =============================================================================
// Clock generator
// Spartan-6 DCM wrapper with parameterized input and output ratios.
// =============================================================================
module clkgen_spartan6_impl #(
parameter integer CLK_IN_HZ = 100000000,
parameter integer CLKFX_DIVIDE = 20,
parameter integer CLKFX_MULTIPLY = 3,
parameter real CLKDV_DIVIDE = 2.0
)(
input wire clk_in,
output wire clk_out
);
`ifdef FPGA_SPARTAN6
localparam real CLKIN_PERIOD_NS = 1000000000.0 / CLK_IN_HZ;
wire clkfb;
wire clk0;
wire clkfx;
wire locked_unused;
wire [7:0] status_unused;
DCM_SP #(
.CLKDV_DIVIDE(CLKDV_DIVIDE),
.CLKFX_DIVIDE(CLKFX_DIVIDE),
.CLKFX_MULTIPLY(CLKFX_MULTIPLY),
.CLKIN_DIVIDE_BY_2("FALSE"),
.CLKIN_PERIOD(CLKIN_PERIOD_NS),
.CLKOUT_PHASE_SHIFT("NONE"),
.CLK_FEEDBACK("1X"),
.DESKEW_ADJUST("SYSTEM_SYNCHRONOUS"),
.PHASE_SHIFT(0),
.STARTUP_WAIT("FALSE")
) dcm_sp_i (
.CLKIN(clk_in),
.CLKFB(clkfb),
.CLK0(clk0),
.CLK90(),
.CLK180(),
.CLK270(),
.CLK2X(),
.CLK2X180(),
.CLKFX(clkfx),
.CLKFX180(),
.CLKDV(),
.PSCLK(1'b0),
.PSEN(1'b0),
.PSINCDEC(1'b0),
.PSDONE(),
.LOCKED(locked_unused),
.STATUS(status_unused),
.RST(1'b0),
.DSSEN(1'b0)
);
BUFG clkfb_buf_i (
.I(clk0),
.O(clkfb)
);
BUFG clkout_buf_i (
.I(clkfx),
.O(clk_out)
);
`else
assign clk_out = 1'b0;
wire _unused_clk_in;
wire _unused_clkfx_divide;
wire _unused_clkfx_multiply;
wire _unused_clkdv_divide;
assign _unused_clk_in = clk_in;
assign _unused_clkfx_divide = CLKFX_DIVIDE[0];
assign _unused_clkfx_multiply = CLKFX_MULTIPLY[0];
assign _unused_clkdv_divide = (CLKDV_DIVIDE != 0.0);
`endif
endmodule

View File

@@ -0,0 +1,34 @@
CAPI=2:
name: joppeb:primitive:jtag_if:1.0
description: JTAG user chain interface
filesets:
wrapper:
files:
- jtag_if.v
file_type: verilogSource
generic:
files:
- jtag_if_generic_impl.v
file_type: verilogSource
spartan6:
files:
- jtag_if_spartan6.v
file_type: verilogSource
targets:
default:
filesets:
- wrapper
- generic
- spartan6
toplevel: jtag_if
parameters:
- chain
parameters:
chain:
datatype: int
description: User chain
paramtype: vlogparam

View File

@@ -0,0 +1,52 @@
`timescale 1ns/1ps
// =============================================================================
// JTAG interface
// Stable public wrapper that selects an implementation.
// =============================================================================
module jtag_if #(
parameter chain = 1
)(
input wire i_tdo,
output wire o_tck,
output wire o_tdi,
output wire o_drck,
output wire o_capture,
output wire o_shift,
output wire o_update,
output wire o_runtest,
output wire o_reset,
output wire o_sel
);
`ifdef FPGA_SPARTAN6
jtag_if_spartan6_impl #(
.chain(chain)
) impl_i (
.i_tdo(i_tdo),
.o_tck(o_tck),
.o_tdi(o_tdi),
.o_drck(o_drck),
.o_capture(o_capture),
.o_shift(o_shift),
.o_update(o_update),
.o_runtest(o_runtest),
.o_reset(o_reset),
.o_sel(o_sel)
);
`else
jtag_if_generic_impl #(
.chain(chain)
) impl_i (
.i_tdo(i_tdo),
.o_tck(o_tck),
.o_tdi(o_tdi),
.o_drck(o_drck),
.o_capture(o_capture),
.o_shift(o_shift),
.o_update(o_update),
.o_runtest(o_runtest),
.o_reset(o_reset),
.o_sel(o_sel)
);
`endif
endmodule

View File

@@ -0,0 +1,36 @@
`timescale 1ns/1ps
// =============================================================================
// JTAG interface
// Generic stub model with inactive/tied-off outputs.
// =============================================================================
module jtag_if_generic_impl #(
parameter chain = 1
)(
input wire i_tdo,
output wire o_tck,
output wire o_tdi,
output wire o_drck,
output wire o_capture,
output wire o_shift,
output wire o_update,
output wire o_runtest,
output wire o_reset,
output wire o_sel
);
assign o_tck = 1'b0;
assign o_tdi = 1'b0;
assign o_drck = 1'b0;
assign o_capture = 1'b0;
assign o_shift = 1'b0;
assign o_update = 1'b0;
assign o_runtest = 1'b0;
assign o_reset = 1'b0;
assign o_sel = 1'b0;
// Keep lint tools quiet in generic builds where TDO is unused.
wire _unused_tdo;
wire _unused_chain;
assign _unused_tdo = i_tdo;
assign _unused_chain = chain[0];
endmodule

View File

@@ -0,0 +1,52 @@
`timescale 1ns/1ps
// =============================================================================
// JTAG interface
// Spartan-6 BSCAN primitive wrapper (USER1 chain).
// =============================================================================
module jtag_if_spartan6_impl #(
parameter chain = 1
)(
input wire i_tdo,
output wire o_tck,
output wire o_tdi,
output wire o_drck,
output wire o_capture,
output wire o_shift,
output wire o_update,
output wire o_runtest,
output wire o_reset,
output wire o_sel
);
`ifdef FPGA_SPARTAN6
BSCAN_SPARTAN6 #(
.JTAG_CHAIN(chain)
) bscan_i (
.CAPTURE(o_capture),
.DRCK(o_drck),
.RESET(o_reset),
.RUNTEST(o_runtest),
.SEL(o_sel),
.SHIFT(o_shift),
.TCK(o_tck),
.TDI(o_tdi),
.TDO(i_tdo),
.UPDATE(o_update)
);
`else
assign o_tck = 1'b0;
assign o_tdi = 1'b0;
assign o_drck = 1'b0;
assign o_capture = 1'b0;
assign o_shift = 1'b0;
assign o_update = 1'b0;
assign o_runtest = 1'b0;
assign o_reset = 1'b0;
assign o_sel = 1'b0;
wire _unused_tdo;
wire _unused_chain;
assign _unused_tdo = i_tdo;
assign _unused_chain = chain[0];
`endif
endmodule