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

16
cores/util/cdc/cdc.core Normal file
View File

@@ -0,0 +1,16 @@
CAPI=2:
name: joppeb:util:cdc:1.0
description: Clock-domain crossing helpers
filesets:
rtl:
files:
- rtl/cdc_strobe_data.v
- rtl/cdc_req_resp.v
file_type: verilogSource
targets:
default:
filesets:
- rtl

View File

@@ -0,0 +1,70 @@
`timescale 1 ns/1 ps
// =============================================================================
// cdc_req_resp
// Bidirectional channel made from two cdc_strobe_data mailboxes.
// =============================================================================
module cdc_req_resp #(
parameter integer REQ_W = 32,
parameter integer RESP_W = 32,
parameter integer STABLE_SAMPLES = 2
)(
// Side A (e.g., JTAG/TCK)
input wire a_clk,
input wire a_rst,
input wire a_req_pulse,
input wire [REQ_W-1:0] a_req_data,
output wire a_req_busy,
output wire a_req_accepted,
output wire a_resp_pulse,
output wire [RESP_W-1:0] a_resp_data,
// Side B (e.g., system/i_clk)
input wire b_clk,
input wire b_rst,
output wire b_req_pulse,
output wire [REQ_W-1:0] b_req_data,
input wire b_resp_pulse,
input wire [RESP_W-1:0] b_resp_data,
output wire b_resp_busy,
output wire b_resp_accepted
);
cdc_strobe_data #(
.WIDTH(REQ_W),
.STABLE_SAMPLES(STABLE_SAMPLES)
) u_req (
.s_clk(a_clk),
.s_rst(a_rst),
.s_pulse(a_req_pulse),
.s_data(a_req_data),
.s_busy(a_req_busy),
.s_accepted(a_req_accepted),
.d_clk(b_clk),
.d_rst(b_rst),
.d_pulse(b_req_pulse),
.d_data(b_req_data)
);
cdc_strobe_data #(
.WIDTH(RESP_W),
.STABLE_SAMPLES(STABLE_SAMPLES)
) u_resp (
.s_clk(b_clk),
.s_rst(b_rst),
.s_pulse(b_resp_pulse),
.s_data(b_resp_data),
.s_busy(b_resp_busy),
.s_accepted(b_resp_accepted),
.d_clk(a_clk),
.d_rst(a_rst),
.d_pulse(a_resp_pulse),
.d_data(a_resp_data)
);
endmodule

View File

@@ -0,0 +1,130 @@
`timescale 1 ns/1 ps
// =============================================================================
// cdc_strobe_data
// - One-deep mailbox for (strobe + data) crossing clock domains.
// - Uses toggle req/ack with 2FF sync for toggles.
// - Wide bus is held stable by source until ack, destination samples-until-stable.
// =============================================================================
module cdc_strobe_data #(
parameter integer WIDTH = 32,
parameter integer STABLE_SAMPLES = 2 // >=2 recommended
)(
// Source domain
input wire s_clk,
input wire s_rst, // async OK (posedge) if used consistently
input wire s_pulse, // strobe (1+ cycles). Accepted when not busy.
input wire [WIDTH-1:0] s_data,
output wire s_busy, // 1 = mailbox full / waiting for ack
output wire s_accepted, // 1-cycle pulse when we accepted s_pulse
// Destination domain
input wire d_clk,
input wire d_rst,
output reg d_pulse, // 1-cycle pulse on new data
output reg [WIDTH-1:0] d_data // updated when d_pulse asserted; held otherwise
);
// ----------------------------
// Source: hold + req toggle
// ----------------------------
reg [WIDTH-1:0] s_hold;
reg s_req_tog;
reg s_inflight;
// Ack toggle synchronized into source domain
(* ASYNC_REG="TRUE" *) reg s_ack_sync1, s_ack_sync2;
assign s_busy = s_inflight;
wire do_accept = s_pulse && !s_inflight;
assign s_accepted = do_accept;
// d_ack_tog is generated in destination domain (declared below as reg)
// and is synced here with 2FF.
always @(posedge s_clk or posedge s_rst) begin
if (s_rst) begin
s_hold <= {WIDTH{1'b0}};
s_req_tog <= 1'b0;
s_inflight <= 1'b0;
s_ack_sync1 <= 1'b0;
s_ack_sync2 <= 1'b0;
end else begin
s_ack_sync1 <= d_ack_tog;
s_ack_sync2 <= s_ack_sync1;
// clear inflight when ack matches current req toggle
if (s_inflight && (s_ack_sync2 == s_req_tog))
s_inflight <= 1'b0;
// accept new item
if (do_accept) begin
s_hold <= s_data;
s_req_tog <= ~s_req_tog;
s_inflight <= 1'b1;
end
end
end
// ----------------------------
// Destination: sync req toggle, sample-until-stable, then ack toggle
// ----------------------------
(* ASYNC_REG="TRUE" *) reg d_req_sync1, d_req_sync2;
reg d_req_seen;
reg d_ack_tog;
reg [WIDTH-1:0] samp;
reg [WIDTH-1:0] samp_prev;
integer stable_cnt;
reg capturing;
wire d_new_req = (d_req_sync2 != d_req_seen);
always @(posedge d_clk or posedge d_rst) begin
if (d_rst) begin
d_req_sync1 <= 1'b0;
d_req_sync2 <= 1'b0;
d_req_seen <= 1'b0;
d_ack_tog <= 1'b0;
d_pulse <= 1'b0;
d_data <= {WIDTH{1'b0}};
samp <= {WIDTH{1'b0}};
samp_prev <= {WIDTH{1'b0}};
stable_cnt <= 0;
capturing <= 1'b0;
end else begin
d_pulse <= 1'b0;
d_req_sync1 <= s_req_tog;
d_req_sync2 <= d_req_sync1;
if (d_new_req && !capturing) begin
capturing <= 1'b1;
stable_cnt <= 0;
samp_prev <= s_hold;
samp <= s_hold;
end else if (capturing) begin
samp <= s_hold;
if (samp == samp_prev) begin
if (stable_cnt < (STABLE_SAMPLES-1))
stable_cnt <= stable_cnt + 1;
else begin
// accept
d_data <= samp;
d_pulse <= 1'b1;
d_req_seen <= d_req_sync2;
d_ack_tog <= ~d_ack_tog;
capturing <= 1'b0;
end
end else begin
stable_cnt <= 0;
end
samp_prev <= samp;
end
end
end
endmodule

View File

@@ -0,0 +1,16 @@
CAPI=2:
name: joppeb:util:clog2:1.0
description: Verilog-2001 compatible ceil(log2(x)) macro header
filesets:
include:
files:
- clog2.vh:
is_include_file: true
file_type: verilogSource
targets:
default:
filesets:
- include

39
cores/util/clog2/clog2.vh Normal file
View File

@@ -0,0 +1,39 @@
`ifndef CLOG2_VH
`define CLOG2_VH
// Verilog-2001 compatible ceil(log2(x)) macro (matches $clog2 semantics).
`define CLOG2(x) \
(((x) <= 1) ? 0 : \
((x) <= 2) ? 1 : \
((x) <= 4) ? 2 : \
((x) <= 8) ? 3 : \
((x) <= 16) ? 4 : \
((x) <= 32) ? 5 : \
((x) <= 64) ? 6 : \
((x) <= 128) ? 7 : \
((x) <= 256) ? 8 : \
((x) <= 512) ? 9 : \
((x) <= 1024) ? 10 : \
((x) <= 2048) ? 11 : \
((x) <= 4096) ? 12 : \
((x) <= 8192) ? 13 : \
((x) <= 16384) ? 14 : \
((x) <= 32768) ? 15 : \
((x) <= 65536) ? 16 : \
((x) <= 131072) ? 17 : \
((x) <= 262144) ? 18 : \
((x) <= 524288) ? 19 : \
((x) <= 1048576) ? 20 : \
((x) <= 2097152) ? 21 : \
((x) <= 4194304) ? 22 : \
((x) <= 8388608) ? 23 : \
((x) <= 16777216) ? 24 : \
((x) <= 33554432) ? 25 : \
((x) <= 67108864) ? 26 : \
((x) <= 134217728) ? 27 : \
((x) <= 268435456) ? 28 : \
((x) <= 536870912) ? 29 : \
((x) <= 1073741824) ? 30 : \
((x) <= 2147483648) ? 31 : 32)
`endif