My code requires that I store the value of an input signal's period in a register. I have mocked up the code below to register the period, but I cant yet confirm that it works. In your experience do you see anything that is immediately wrong with it. I am trying to learn how to use modelsim at the moment please forgive me. Sys_clk is a 50MHz clock, and the in_signal I am working with right now is 2Hz but that may change.Desired Inputs: System Clock, RST from controller, a signal of unknown frequency and duty cycle that is less than 50MHz(the freq is constant). Desired Output: A registered period value in decimal form <!-- language: verilog -->module t_sampler(input wire in_signal, input sys_clk, output reg [31:0] total_T);reg [31:0] pos_length;reg [31:0] neg_length;reg pos_cntstop;reg neg_cntstop;always @ (posesge sys_clk) beginif (in_signal) begin pos_length <= pos_length + 1; end else begin pos_length <= pos_length; pos_cntstop <= 1; endif (!in_signal) begin neg_length <= neg_length + 1; end else begin neg_length <= neg_length; neg_cntstop <= 1; endif (neg_cntstop && pos_cntstop) begin total_T <= neg_length + pos_length; neg_cntstop <= 0; neg_length <= 0; pos_cntstop <= 0; pos_length <= 0; endendendmodule
When attaching code fragments to posts use the advanced editor and put the "code" tags around it. Otherwise all your line breaks will be lost like what happened in your original post.
I see several things wrong with it.1) Like sstrell said, "posedge" is spelled wrong. 2) There is no initial values or reset for the pos_length and neg_length registers. While the FPGA will initialize with these zero the simulation will have the values of "x" and "x" plus 1 remains "x". 3) same issues with pos_cntstop and neg_cntstop 3) the sequencing of the high period count and low period count is just not right. Assume that at time 0 in_signal is high, which will allow pos_length to start counting. Also assume pos_cntstop is negated. Because in_signal is not low neg_cntstop will be asserted. As soon as the in_signal goes low, pos_cntstop will be asserted. On the next clock edge neg_length will begin counting, but neg_cntstop is already asserted from the previous high period. Because pos_cntstop and neg_cntstop are both asserted you will clear both the counts and the "stop" bits. Your register total_T will only show half the clock period. 4) There is also a major problem if in_signal is not synchronous to sys_clk. An asynchronous signal applied to the enable of counter is guaranteed to fail. You would be better off to have a single period counter and count the time between rising edges of in_signal. First, double register "in_signal" to get it into sys_clk domain. Then have one more register: in_signal_sync_dly. The riding edge can be detected from In_signal_sync & !in_signal_sync_dly. So, it becomes:
always @(posesge sys_clk)begin in_signal_sync0 <= in_signal; in_signal_sync <= in_signal_sync0; in_signal_sync_dly <= in_signal_sync; if (reset) begin total_T <= 32'h0; legnth_count <= 32'h0; end // of reset else begin if (in_signal_sync && !in_signal_sync_dly) begin total_T <= legnth_count; legnth_count <= 32'h0; end else begin legnth_count <= legnth_count + 32'h1; end end // of not reset end // of always