64 lines
1.4 KiB
Verilog
64 lines
1.4 KiB
Verilog
/* Calculate and truncate Δt = cycles/100MhZ.
|
|
* NOTE: boothmul is a SIGNED algorithm so both inputs are SIGNED.
|
|
* This means that SEC_PER_CYCLE must have a leading 0
|
|
* and that cycles must also have a leading zero.
|
|
*/
|
|
|
|
`undefineall
|
|
module calculate_dt #(
|
|
/* This number is 1/(clock cycle).
|
|
The number is interpreted so the least significant bit
|
|
coincides with the LSB of a constant. */
|
|
parameter SEC_PER_CYCLE_WID = 15,
|
|
parameter [SEC_PER_CYCLE_WID-1:0] SEC_PER_CYCLE = 'b010101011110011,
|
|
parameter CYCLE_COUNT_WID = 18,
|
|
parameter MAX_WID = 48
|
|
) (
|
|
input clk,
|
|
input arm,
|
|
output finished,
|
|
|
|
input [CYCLE_COUNT_WID-1:0] cycles,
|
|
|
|
/* Multiplication of Q18.0 and 14 lower siginifcant bits. */
|
|
`define DT_WID_UNTRUNC (SEC_PER_CYCLE_WID + CYCLE_COUNT_WID)
|
|
`define DT_WID (`DT_WID_UNTRUNC > MAX_WID ? MAX_WID : `DT_WID_UNTRUNC)
|
|
|
|
output [`DT_WID-1:0] dt
|
|
);
|
|
|
|
wire [`DT_WID_UNTRUNC-1:0] dt_untrunc;
|
|
|
|
boothmul #(
|
|
.A1_LEN(CYCLE_COUNT_WID),
|
|
.A2_LEN(SEC_PER_CYCLE_WID)
|
|
) mul (
|
|
.clk(clk),
|
|
.arm(arm),
|
|
.a1(cycles),
|
|
.a2(SEC_PER_CYCLE),
|
|
.outn(dt_untrunc),
|
|
.fin(finished)
|
|
);
|
|
|
|
generate if (`DT_WID_UNTRUNC > `DT_WID) begin
|
|
intsat #(
|
|
.IN_LEN(`DT_WID_UNTRUNC),
|
|
.LTRUNC(`DT_WID_UNTRUNC - `DT_WID)
|
|
) sat (
|
|
.inp(dt_untrunc),
|
|
.outp(dt)
|
|
);
|
|
end else begin
|
|
assign dt = dt_untrunc;
|
|
end endgenerate
|
|
|
|
`ifdef VERILATOR
|
|
initial begin
|
|
$dumpfile("calculate_dt.fst");
|
|
$dumpvars;
|
|
end
|
|
`endif
|
|
|
|
endmodule
|