axis_pps_counter.v 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. `timescale 1 ns / 1 ps
  2. module axis_pps_counter #
  3. (
  4. parameter integer AXIS_TDATA_WIDTH = 32,
  5. parameter integer CNTR_WIDTH = 32
  6. )
  7. (
  8. // System signals
  9. input wire aclk,
  10. input wire aresetn,
  11. input wire pps_data,
  12. // Master side
  13. output wire [AXIS_TDATA_WIDTH-1:0] m_axis_tdata,
  14. output wire m_axis_tvalid
  15. );
  16. reg [CNTR_WIDTH-1:0] int_cntr_reg;
  17. reg int_enbl_reg;
  18. reg [1:0] int_data_reg;
  19. wire int_edge_wire, int_pps_wire;
  20. xpm_cdc_single #(
  21. .DEST_SYNC_FF(4),
  22. .INIT_SYNC_FF(0),
  23. .SRC_INPUT_REG(0),
  24. .SIM_ASSERT_CHK(0)
  25. ) cdc_0 (
  26. .src_in(pps_data),
  27. .src_clk(),
  28. .dest_out(int_pps_wire),
  29. .dest_clk(aclk)
  30. );
  31. always @(posedge aclk)
  32. begin
  33. if(~aresetn)
  34. begin
  35. int_cntr_reg <= {(CNTR_WIDTH){1'b0}};
  36. int_enbl_reg <= 1'b0;
  37. int_data_reg <= 2'd0;
  38. end
  39. else
  40. begin
  41. int_cntr_reg <= int_edge_wire ? {(CNTR_WIDTH){1'b0}} : int_cntr_reg + 1'b1;
  42. int_enbl_reg <= int_edge_wire ? 1'b1 : int_enbl_reg;
  43. int_data_reg <= {int_data_reg[0], ~int_pps_wire};
  44. end
  45. end
  46. assign int_edge_wire = int_data_reg[1] & ~int_data_reg[0];
  47. assign m_axis_tdata = {{(AXIS_TDATA_WIDTH-CNTR_WIDTH){1'b0}}, int_cntr_reg};
  48. assign m_axis_tvalid = int_enbl_reg & int_edge_wire;
  49. endmodule