3signal.v 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820
  1. /*
  2. * 3signal.v
  3. *
  4. * vim: ts=4 sw=4
  5. *
  6. * Copyright (C) 2025 Krzysztof Skrzynecki, Jakub Duchniewicz <j.duchniewicz@gmail.com>
  7. * SPDX-License-Identifier: TODO:
  8. */
  9. `default_nettype none
  10. module compare_eq#(
  11. parameter WIDTH = 16
  12. )(
  13. input wire clk,
  14. input wire [WIDTH-1:0] A,
  15. input wire [WIDTH-1:0] B,
  16. output reg [0:0] was_eq //1 if A and B were equal 2 ticks ago
  17. );
  18. parameter WIDTH_DIV4 = (WIDTH+3)/4;
  19. parameter WIDTH_REM = WIDTH - WIDTH_DIV4*3;
  20. wire [WIDTH_DIV4-1:0] A0_pt0, A0_pt1, A0_pt2;
  21. wire [WIDTH_REM-1:0] A0_pt3;
  22. wire [WIDTH_DIV4-1:0] B0_pt0, B0_pt1, B0_pt2;
  23. wire [WIDTH_REM-1:0] B0_pt3;
  24. assign {A0_pt3, A0_pt2, A0_pt1, A0_pt0} = A;
  25. assign {B0_pt3, B0_pt2, B0_pt1, B0_pt0} = B;
  26. reg pt0_eq, pt1_eq, pt2_eq, pt3_eq;
  27. always @(posedge clk) begin
  28. pt0_eq <= A0_pt0==B0_pt0;
  29. pt1_eq <= A0_pt1==B0_pt1;
  30. pt2_eq <= A0_pt2==B0_pt2;
  31. pt3_eq <= A0_pt3==B0_pt3;
  32. was_eq <= pt0_eq & pt1_eq & pt2_eq & pt3_eq;
  33. end
  34. endmodule
  35. module full_adder #(
  36. parameter WIDTH = 1
  37. ) (
  38. input wire [WIDTH-1:0] A,
  39. input wire [WIDTH-1:0] B,
  40. input wire carry_in,
  41. output wire [WIDTH-1:0] sum,
  42. output wire carry_out
  43. );
  44. assign {carry_out, sum} = A + B + {{(WIDTH-1){1'b0}},carry_in};
  45. endmodule
  46. module add #( // will glitch for WIDTH/CHUNK_WIDTH cycles
  47. parameter WIDTH = 16,
  48. parameter CHUNK_WIDTH = 4
  49. ) (
  50. input wire clk,
  51. input wire [WIDTH-1:0] A,
  52. input wire [WIDTH-1:0] B,
  53. output reg [WIDTH-1:0] sum,
  54. output reg carry_out
  55. );
  56. localparam NUM_CHUNKS = (WIDTH + CHUNK_WIDTH - 1) / CHUNK_WIDTH;
  57. reg [NUM_CHUNKS:0] carry;
  58. genvar i;
  59. generate
  60. for (i = 0; i < NUM_CHUNKS; i = i + 1) begin : gen_adder
  61. localparam ACTUAL_WIDTH = ((i + 1) * CHUNK_WIDTH > WIDTH) ? (WIDTH - i * CHUNK_WIDTH) : CHUNK_WIDTH;
  62. reg [ACTUAL_WIDTH-1:0] sum_wire;
  63. reg carry_out_wire;
  64. full_adder #(.WIDTH(ACTUAL_WIDTH)) adder_inst (
  65. .A(A[i * CHUNK_WIDTH +: ACTUAL_WIDTH]),
  66. .B(B[i * CHUNK_WIDTH +: ACTUAL_WIDTH]),
  67. .carry_in(carry[i]),
  68. .sum(sum_wire),
  69. .carry_out(carry_out_wire)
  70. );
  71. always @(posedge clk) begin
  72. sum[i * CHUNK_WIDTH +: ACTUAL_WIDTH] <= sum_wire;
  73. carry[i + 1] <= carry_out_wire;
  74. end
  75. end
  76. endgenerate
  77. always @(posedge clk) begin
  78. carry[0] <= 1'b0;
  79. end
  80. assign carry_out = carry[NUM_CHUNKS];
  81. endmodule
  82. module compare_gt #(
  83. parameter WIDTH = 16
  84. ) (
  85. input wire clk,
  86. input wire [WIDTH-1:0] A,
  87. input wire [WIDTH-1:0] B,
  88. output reg was_gt,
  89. output reg was_eq
  90. );
  91. generate
  92. if (WIDTH <= 2) begin : base_case
  93. // Base case: direct 2-bit comparison
  94. always @(posedge clk) begin
  95. was_gt <= A > B;
  96. was_eq <= A == B;
  97. end
  98. end else begin : recursive_case
  99. // Recursive submodules for upper & lower halves
  100. reg gt_upper, eq_upper, gt_lower, eq_lower;
  101. compare_gt #(WIDTH-WIDTH/2) upper (
  102. .clk(clk),
  103. .A(A[WIDTH-1:WIDTH/2]),
  104. .B(B[WIDTH-1:WIDTH/2]),
  105. .was_gt(gt_upper),
  106. .was_eq(eq_upper)
  107. );
  108. compare_gt #(WIDTH/2) lower (
  109. .clk(clk),
  110. .A(A[WIDTH/2-1:0]),
  111. .B(B[WIDTH/2-1:0]),
  112. .was_gt(gt_lower),
  113. .was_eq(eq_lower)
  114. );
  115. always @(posedge clk) begin
  116. was_gt <= gt_upper | (eq_upper & gt_lower);
  117. was_eq <= eq_upper & eq_lower;
  118. end
  119. end
  120. endgenerate
  121. endmodule
  122. //module compare_gt#(
  123. // parameter WIDTH = 16
  124. //)(
  125. // input wire clk,
  126. //
  127. // input wire [WIDTH-1:0] A,
  128. // input wire [WIDTH-1:0] B,
  129. //
  130. // output reg [0:0] was_gt //1 if A was greater than B 3 ticks ago
  131. //);
  132. // parameter WIDTH_DIV4 = (WIDTH+3)/4;
  133. // parameter WIDTH_REM = WIDTH - WIDTH_DIV4*3;
  134. //
  135. // reg [WIDTH_DIV4-1:0] A0_pt0x, A0_pt1x, A0_pt2x;
  136. // reg [WIDTH_REM-1:0] A0_pt3x;
  137. //
  138. // reg [WIDTH_DIV4-1:0] B0_pt0x, B0_pt1x, B0_pt2x;
  139. // reg [WIDTH_REM-1:0] B0_pt3x;
  140. //
  141. // reg [WIDTH_DIV4-1:0] A0_pt0y, A0_pt1y, A0_pt2y;
  142. // reg [WIDTH_REM-1:0] A0_pt3y;
  143. //
  144. // reg [WIDTH_DIV4-1:0] B0_pt0y, B0_pt1y, B0_pt2y;
  145. // reg [WIDTH_REM-1:0] B0_pt3y;
  146. //
  147. // //assign {A0_pt3, A0_pt2, A0_pt1, A0_pt0} = Ab;
  148. // //assign {B0_pt3, B0_pt2, B0_pt1, B0_pt0} = Bb;
  149. //
  150. // reg pt0_gt, pt1_gt, pt2_gt, pt3_gt;
  151. // reg pt0_eq, pt1_eq, pt2_eq, pt3_eq;
  152. //
  153. // reg pt01_eq, pt23_eq;
  154. // reg pt01_gt, pt23_gt;
  155. //
  156. // reg [WIDTH-1:0] Ab, Bb; // buffer regs for shorter wires
  157. //
  158. // always @(posedge clk) begin
  159. // Ab <= A;
  160. // Bb <= B;
  161. //
  162. // {A0_pt3x, A0_pt2x, A0_pt1x, A0_pt0x} <= Ab;
  163. // {B0_pt3x, B0_pt2x, B0_pt1x, B0_pt0x} <= Bb;
  164. //
  165. // {A0_pt3y, A0_pt2y, A0_pt1y, A0_pt0y} <= Ab;
  166. // {B0_pt3y, B0_pt2y, B0_pt1y, B0_pt0y} <= Bb;
  167. //
  168. // pt0_gt <= A0_pt0x>B0_pt0x;
  169. // pt1_gt <= A0_pt1x>B0_pt1x;
  170. // pt2_gt <= A0_pt2x>B0_pt2x;
  171. // pt3_gt <= A0_pt3x>B0_pt3x;
  172. //
  173. // pt0_eq <= A0_pt0y==B0_pt0y;
  174. // pt1_eq <= A0_pt1y==B0_pt1y;
  175. // pt2_eq <= A0_pt2y==B0_pt2y;
  176. // pt3_eq <= A0_pt3y==B0_pt3y;
  177. //
  178. // pt01_eq <= pt0_eq & pt1_eq;
  179. // pt01_gt <= pt1_gt | (pt1_eq & pt0_gt);
  180. //
  181. // pt23_eq <= pt2_eq & pt3_eq;
  182. // pt23_gt <= pt3_gt | (pt3_eq & pt2_gt);
  183. //
  184. // was_gt <= pt23_gt | (pt23_eq & pt01_gt);
  185. // end
  186. //
  187. //endmodule
  188. module cycle_trigger#(
  189. parameter WIDTH = 16
  190. ) (
  191. input wire /*nrst,*/ clk,
  192. input wire [WIDTH-1:0] period,
  193. output reg [0:0] start_cycle,
  194. output reg [0:0] half_cycle,
  195. output reg [2:0] trig_out
  196. );
  197. reg [WIDTH-1:0] counter;
  198. reg [WIDTH-1:0] counter_delayed;// just to make placement easier - less branches from counter
  199. reg [WIDTH-1:0] period_div2;
  200. reg [WIDTH-1:0] period_shadow;
  201. wire zero;
  202. always @(posedge clk /*or negedge nrst*/) begin
  203. /*if (!nrst) begin
  204. counter <= 0;
  205. //period_div2 <= 16'h0;
  206. high_match_a <= 0;
  207. high_match_b <= 0;
  208. half_match_a <= 0;
  209. half_match_b <= 0;
  210. start_cycle <= 0;
  211. half_cycle <= 0;
  212. trig_out <= 0;
  213. end else begin*/
  214. if(zero) begin
  215. start_cycle <= 1;
  216. period_div2 <= period>>1;
  217. period_shadow <= period;
  218. end else begin
  219. start_cycle <= 0;
  220. end
  221. if (start_cycle) begin
  222. counter <= period_shadow;
  223. end else begin
  224. counter <= counter-1;
  225. end
  226. counter_delayed <= counter;
  227. //end //nrst
  228. end
  229. compare_eq#(.WIDTH(WIDTH))cmp_zero(
  230. .clk(clk),
  231. .A(counter_delayed),
  232. .B(0),
  233. .was_eq(zero)
  234. );
  235. compare_eq#(.WIDTH(WIDTH))cmp_half(
  236. .clk(clk),
  237. .A(counter_delayed),
  238. .B(period_div2),
  239. .was_eq(half_cycle)
  240. );
  241. compare_eq#(.WIDTH(WIDTH))cmp0(
  242. .clk(clk),
  243. .A(counter_delayed),
  244. .B(3),
  245. .was_eq(trig_out[0])
  246. );
  247. compare_eq#(.WIDTH(WIDTH))cmp1(
  248. .clk(clk),
  249. .A(counter_delayed),
  250. .B(3),
  251. .was_eq(trig_out[1])
  252. );
  253. compare_eq#(.WIDTH(WIDTH))cmp2(
  254. .clk(clk),
  255. .A(counter_delayed),
  256. .B(9),
  257. .was_eq(trig_out[2])
  258. );
  259. endmodule
  260. /*module continous_pwm_gen#(
  261. parameter WIDTH = 16
  262. ) (
  263. input wire nrst, clk,
  264. input wire [WIDTH-1:0] period,
  265. input wire [WIDTH-1:0] delay,
  266. output reg [0:0] pwm_out
  267. );
  268. reg [WIDTH-1:0] counter;
  269. reg [WIDTH-1:0] _period;
  270. reg [WIDTH-1:0] _delay;
  271. reg [0:0] next_out;
  272. reg [0:0] is_last_tick;
  273. reg [0:0] is_last_tickA;
  274. reg [0:0] is_last_tickB;
  275. reg [0:0] is_mid_tick;
  276. // Counter logic
  277. always @(posedge clk or negedge nrst) begin
  278. if (!nrst) begin
  279. counter <= 0;
  280. pwm_out <= 0;
  281. next_out <= 0;
  282. _period <= 0;
  283. _delay <= 0;
  284. is_last_tick <= 0;
  285. is_last_tickA <= 0;
  286. is_last_tickB <= 0;
  287. end else begin
  288. _period <= period;
  289. _delay <= delay;
  290. is_last_tickA <= counter[WIDTH-1:8]==0;
  291. is_last_tickB <= counter[7:0]==2;
  292. is_last_tick <= is_last_tickA&is_last_tickB;
  293. if (is_last_tick) begin
  294. counter <= _period;
  295. end else begin
  296. counter <= counter-1;
  297. end
  298. next_out <= is_last_tick;
  299. pwm_out <= next_out;
  300. end
  301. end
  302. endmodule*/
  303. module single_shot_gen#(
  304. parameter WIDTH = 16
  305. )(
  306. input wire nrst,clk,
  307. input wire trigger,
  308. input [WIDTH-1:0] delay,
  309. input [WIDTH-1:0] period,
  310. output reg pwm_out
  311. );
  312. reg [WIDTH-1:0] counter;
  313. reg [WIDTH-1:0] counter2; // Buffer register for better timing
  314. wire pwm_gt;
  315. always @(posedge clk) begin
  316. if (trigger) begin
  317. counter <= period; //########TODO WARNING: counter will underflow which may trigger unwanted pulses. Add logic to fix that.
  318. end else begin
  319. counter <= counter - 1;
  320. end
  321. // Buffer register to reduce timing pressure
  322. counter2 <= counter;
  323. // Output register to reduce delay
  324. pwm_out <= pwm_gt;
  325. end
  326. // Parallel comparison with buffered counter
  327. wire unused;
  328. compare_gt #(.WIDTH(WIDTH)) cmp_out (
  329. .clk(clk),
  330. .A(delay),
  331. .B(counter2),
  332. .was_gt(pwm_gt),
  333. .was_eq(unused)
  334. );
  335. endmodule
  336. /*module phase_delay#(
  337. parameter WIDTH = 16,
  338. parameter FORWARD_DATA_WIDTH = 16
  339. )(
  340. input wire nrst, clk,
  341. input wire in_trig,
  342. input [WIDTH-1:0] delay,
  343. input [FORWARD_DATA_WIDTH-1:0] in_data_fwd,
  344. output wire out_trig,
  345. output reg [FORWARD_DATA_WIDTH-1:0] out_data_fwd
  346. );
  347. reg [WIDTH-1:0] counter;
  348. reg [0:0] is_counting;
  349. reg [WIDTH-1:0] delay_latched;
  350. always @(posedge clk or negedge nrst) begin
  351. if (!nrst) begin
  352. counter <= 0;
  353. is_counting <=0;
  354. delay_latched <=0;
  355. end else begin
  356. if (is_counting) begin
  357. if ((counter+1) >= delay_latched) begin
  358. counter <= 0;
  359. is_counting <= 0;
  360. end else begin
  361. counter <= counter+1;
  362. end
  363. end else begin
  364. if (in_trig) begin
  365. is_counting <= 1;
  366. out_data_fwd <= in_data_fwd;
  367. delay_latched <= delay;
  368. end
  369. end
  370. end
  371. end
  372. assign out_trig=((counter+1)>=delay) && is_counting;
  373. endmodule*/
  374. module simple_counter#(
  375. parameter WIDTH = 14
  376. )(
  377. input wire clk,
  378. input wire trigger,
  379. input wire if_counting,
  380. output reg [WIDTH-1:0] cnt_out
  381. );
  382. parameter HALF_WIDTH=7;
  383. reg [HALF_WIDTH-1:0] cnt1, cnt0;
  384. wire cnt0f;
  385. reg update_cnt1_next_cycle;
  386. assign cnt0f = (&cnt0[HALF_WIDTH-1:1]) & (!cnt0[0]) ;
  387. always @(posedge clk /*or negedge nrst*/) begin
  388. if (trigger) begin
  389. cnt1 <= 0;
  390. cnt0 <= 0;
  391. update_cnt1_next_cycle <= 0;
  392. end else begin
  393. //cnt1f <= &cnt1;
  394. if(if_counting) begin
  395. cnt0 <= cnt0+1;
  396. update_cnt1_next_cycle<=cnt0f;
  397. if(update_cnt1_next_cycle) begin
  398. cnt1 <= cnt1+1;
  399. end
  400. end
  401. cnt_out <= {cnt1, cnt0};
  402. end
  403. end
  404. endmodule
  405. module pulse_train_gen#(
  406. parameter TOTAL_PERIOD_WIDTH = 14,
  407. parameter SINGLE_CYCLE_WIDTH = 8,
  408. parameter PULSE_COUNTER_WIDTH = 8
  409. )(
  410. input wire nrst, clk,
  411. input wire trigger,
  412. input [PULSE_COUNTER_WIDTH-1:0] npuls,
  413. input [SINGLE_CYCLE_WIDTH-1:0] period,
  414. output reg [0:0] trig_out
  415. );
  416. reg [TOTAL_PERIOD_WIDTH-1:0] counter;//total waveform counter
  417. reg [TOTAL_PERIOD_WIDTH-1:0] counter2;
  418. reg [TOTAL_PERIOD_WIDTH-1:0] cycle_threshold;
  419. reg [TOTAL_PERIOD_WIDTH-1:0] cycle_threshold2;
  420. reg [TOTAL_PERIOD_WIDTH-1:0] next_cycle_threshold;
  421. reg [PULSE_COUNTER_WIDTH-1:0] cycle_counter;
  422. reg [PULSE_COUNTER_WIDTH-1:0] next_cycle_counter;
  423. reg [SINGLE_CYCLE_WIDTH-1:0] _period;
  424. reg if_next_cycle;
  425. reg if_next_cycle2;
  426. reg if_next_cycle2b;
  427. reg next_cycle_condition;
  428. reg is_counting;
  429. reg is_counting2;
  430. reg is_counting2b;
  431. reg _trigger;
  432. //reg [3:0] first_trig_ctr, next_first_trig_ctr;
  433. always @(posedge clk /*or negedge nrst*/) begin
  434. /*if (!nrst) begin
  435. is_counting <= 0;
  436. end else begin*/
  437. _trigger<=trigger;
  438. if(_trigger) begin
  439. cycle_threshold <= 10; //{6'b0, _period};
  440. cycle_counter <= npuls;
  441. //first_trig_ctr <= 5;
  442. //next_first_trig_ctr <= 4;
  443. end else begin
  444. //counter <= counter + is_counting2;
  445. end
  446. counter2 <= counter;
  447. _period <= period;
  448. if_next_cycle2 <= if_next_cycle;
  449. if_next_cycle2b <= if_next_cycle;
  450. next_cycle_condition <= if_next_cycle2b & is_counting2;
  451. if(next_cycle_condition & !_trigger) begin
  452. cycle_counter <= next_cycle_counter;
  453. cycle_threshold <= next_cycle_threshold;
  454. end
  455. next_cycle_counter <= cycle_counter-1;
  456. is_counting <= |cycle_counter;
  457. is_counting2 <= is_counting;
  458. is_counting2b <= is_counting;
  459. /*if(first_trig_ctr!=0)
  460. first_trig_ctr<=next_first_trig_ctr;
  461. next_first_trig_ctr<=first_trig_ctr-1;*/
  462. trig_out <= if_next_cycle2;//|(next_first_trig_ctr==0);
  463. cycle_threshold2 <= cycle_threshold;
  464. //end
  465. end
  466. simple_counter cnt(
  467. .clk(clk),//in
  468. .trigger(_trigger),//in
  469. .if_counting(is_counting2b),//in
  470. .cnt_out(counter)//out
  471. );
  472. /*compare_eq#(.WIDTH(TOTAL_PERIOD_WIDTH))cmp_cycle(
  473. .clk(clk),
  474. .A(counter2),
  475. .B(cycle_threshold2),
  476. .was_eq(if_next_cycle)
  477. );*/
  478. wire unused_gt;
  479. compare_gt #(
  480. .WIDTH(TOTAL_PERIOD_WIDTH)
  481. )cmp_cycle (
  482. .clk(clk),
  483. .A(counter2),
  484. .B(cycle_threshold2),
  485. .was_gt(unused_gt),
  486. .was_eq(if_next_cycle)
  487. );
  488. wire unused_carry;
  489. add#(
  490. .WIDTH(TOTAL_PERIOD_WIDTH),
  491. .CHUNK_WIDTH(1)
  492. )cycle_th(
  493. .clk(clk),
  494. .A(cycle_threshold2),
  495. .B({6'b0, _period}),
  496. .sum(next_cycle_threshold),
  497. .carry_out(unused_carry)
  498. );
  499. endmodule
  500. /*module fixed_pulse_extender(
  501. input wire clk,
  502. input wire trigger,
  503. output reg out
  504. );
  505. reg [3:0] cnt;
  506. reg [3:0] next_cnt;
  507. reg is_counting;
  508. always @(posedge clk) begin
  509. is_counting <= (cnt>0) & is_counting;
  510. //next_cnt <= cnt-1;
  511. if(trigger) begin
  512. cnt <= 15;
  513. //next_cnt <= 15;
  514. is_counting <= 1;
  515. end else begin
  516. if(is_counting) begin
  517. cnt <= cnt-1;//next_cnt;
  518. end
  519. end
  520. out <= is_counting;
  521. end
  522. endmodule*/
  523. module pulse_extender_adjustable#(
  524. parameter SINGLE_CYCLE_WIDTH = 8
  525. )(
  526. input wire clk,
  527. input wire cfg_latch_trigger,
  528. input wire pulse_trigger,
  529. input wire [SINGLE_CYCLE_WIDTH-1:0] pulse_width,
  530. output reg pwm_out
  531. );
  532. always @(posedge clk) begin
  533. pwm_out <= pulse_trigger;
  534. end
  535. endmodule
  536. parameter [1:0] ODD_TRAIN_FORCE_OFF = 2'b00;
  537. parameter [1:0] ODD_TRAIN_ENA_CONTROL = 2'b01;
  538. parameter [1:0] ODD_TRAIN_FORCE_ON = 2'b10;
  539. module three_signal#(
  540. parameter FAST_PWM_WIDTH=8,
  541. parameter PULSE_COUNTER_WIDTH=8,
  542. parameter SLOW_PWM_WIDTH=14
  543. )(
  544. input wire nrst, clk,
  545. input [SLOW_PWM_WIDTH-1:0] period1,
  546. input [SLOW_PWM_WIDTH-1:0] delay1,
  547. input [SLOW_PWM_WIDTH-1:0] period2,
  548. input [SLOW_PWM_WIDTH-1:0] delay2,
  549. input [FAST_PWM_WIDTH-1:0] period3,
  550. input [FAST_PWM_WIDTH-1:0] duty3,
  551. input [SLOW_PWM_WIDTH-1:0] delay3,//delay is wrt slow pwm, thus longer bit length
  552. input [PULSE_COUNTER_WIDTH-1:0] npuls3,
  553. input /*odd_train_flag_t*/ wire [1:0] odd_train_flag,
  554. input wire ena_odd_out3,
  555. output reg Out1,
  556. output reg Out2,
  557. output reg Out3
  558. );
  559. reg [SLOW_PWM_WIDTH-1:0] _period1;
  560. reg [SLOW_PWM_WIDTH-1:0] _delay1;
  561. reg [SLOW_PWM_WIDTH-1:0] _duty1;
  562. reg [SLOW_PWM_WIDTH-1:0] _period2;
  563. reg [SLOW_PWM_WIDTH-1:0] _delay2;
  564. reg [FAST_PWM_WIDTH-1:0] _period3;
  565. reg [FAST_PWM_WIDTH-1:0] _duty3;
  566. reg [SLOW_PWM_WIDTH-1:0] _delay3;//delay is wrt slow pwm, thus longer bit length
  567. reg [PULSE_COUNTER_WIDTH-1:0] _npuls3;
  568. reg /*odd_train_flag_t*/ [1:0] _odd_train_flag;
  569. reg _ena_odd_out3;
  570. wire _Out1;
  571. wire _Out2;
  572. wire _Out3;
  573. always @(posedge clk) begin
  574. _period1 <= period1 ;
  575. _delay1 <= delay1 ;
  576. _period2 <= period2 ;
  577. _delay2 <= delay2 ;
  578. _period3 <= period3 ;
  579. _duty3 <= duty3 ;
  580. _delay3 <= delay3 ;
  581. _npuls3 <= npuls3 ;
  582. _odd_train_flag <= odd_train_flag;
  583. _ena_odd_out3 <= ena_odd_out3 ;
  584. //TODO - output already as reg; no additional latency needed?
  585. Out1 <= _Out1;
  586. Out2 <= _Out2;
  587. Out3 <= _Out3;
  588. end
  589. //wire trigger_next_cycle;
  590. //wire trigger_even_cycle;
  591. //wire trigger_odd_cycle;
  592. //wire [SLOW_PWM_WIDTH-1:0] delay3_part1;
  593. //wire [SLOW_PWM_WIDTH-1:0] delay3_part234;
  594. //assign delay3_part234 = delay3>>2;
  595. //assign delay3_part1 = (delay3<4) ? 0 : (delay3 - (delay3_part234*3));
  596. wire [0:0] start_cycle;
  597. wire [0:0] half_cycle;
  598. wire [2:0] trig_out;
  599. cycle_trigger #(.WIDTH(SLOW_PWM_WIDTH)) cyc_trig(
  600. //.nrst(nrst),
  601. .clk(clk),
  602. .period(_period1),
  603. .start_cycle(start_cycle),
  604. .half_cycle(half_cycle),
  605. .trig_out(trig_out)
  606. );
  607. single_shot_gen #(.WIDTH(SLOW_PWM_WIDTH)) pwm1(
  608. .nrst(nrst),
  609. .clk(clk),
  610. .trigger(trig_out[0]),
  611. .delay(_delay1),
  612. .period(_period1),
  613. .pwm_out(_Out1)
  614. );
  615. single_shot_gen #(.WIDTH(SLOW_PWM_WIDTH)) pwm2(
  616. .nrst(nrst),
  617. .clk(clk),
  618. .trigger(trig_out[1]),
  619. .delay(_delay2),
  620. .period(_period2),
  621. .pwm_out(_Out2)
  622. );
  623. wire out3_pulse_trig;
  624. pulse_train_gen#(
  625. .TOTAL_PERIOD_WIDTH(SLOW_PWM_WIDTH),
  626. .SINGLE_CYCLE_WIDTH(FAST_PWM_WIDTH),
  627. .PULSE_COUNTER_WIDTH(PULSE_COUNTER_WIDTH)
  628. )pwm3(
  629. .nrst(nrst),
  630. .clk(clk),
  631. .trigger(trig_out[2]),
  632. .npuls(_npuls3),
  633. .period(_period3),
  634. .trig_out(out3_pulse_trig)
  635. );
  636. pulse_extender_adjustable pext1(
  637. .clk(clk),
  638. .cfg_latch_trigger(trig_out[2]),
  639. .pulse_trigger(out3_pulse_trig),
  640. .pulse_width(_duty3),
  641. .pwm_out(_Out3)
  642. );
  643. /*wire trigger_delay_1_to_2;
  644. wire trigger_delay_2_to_3;
  645. wire trigger_delay_3_to_4;
  646. wire trigger_delay_4_to_pulse_train;
  647. localparam FORWARD_DATA_WIDTH = SLOW_PWM_WIDTH + PULSE_COUNTER_WIDTH + FAST_PWM_WIDTH + FAST_PWM_WIDTH;
  648. localparam DELAY_BITS_POS = PULSE_COUNTER_WIDTH + FAST_PWM_WIDTH + FAST_PWM_WIDTH;
  649. wire [FORWARD_DATA_WIDTH-1:0] data_1_to_2;
  650. wire [FORWARD_DATA_WIDTH-1:0] data_2_to_3;
  651. wire [FORWARD_DATA_WIDTH-1:0] data_3_to_4;
  652. wire [FORWARD_DATA_WIDTH-1:0] data_4_to_gen;
  653. assign trigger_odd_cycle =
  654. (odd_train_flag == ODD_TRAIN_ENA_CONTROL) ? trigger_next_cycle && ena_odd_out3 :
  655. (odd_train_flag == ODD_TRAIN_FORCE_ON) ? trigger_next_cycle :
  656. 0;
  657. wire [FAST_PWM_WIDTH-1:0] period3_gen;
  658. wire [FAST_PWM_WIDTH-1:0] duty3_gen;
  659. wire [PULSE_COUNTER_WIDTH-1:0] npuls3_gen;
  660. assign duty3_gen = data_4_to_gen[FAST_PWM_WIDTH-1:0];
  661. assign period3_gen = data_4_to_gen[FAST_PWM_WIDTH+FAST_PWM_WIDTH-1:FAST_PWM_WIDTH];
  662. assign npuls3_gen = data_4_to_gen[FAST_PWM_WIDTH+FAST_PWM_WIDTH+PULSE_COUNTER_WIDTH-1:FAST_PWM_WIDTH+FAST_PWM_WIDTH];*/
  663. endmodule