Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Your code looks bad to me (which I guess you want to hear as your code doesn't work). It looks like a combination of timing problems and a design flaw.</p> <p>Let's walk through your waveform view and see if we can't work out what's going on.</p> <p>signal in goes high, which triggers an always block. PS is 0 so we set NS to 1. This is not in time for the rising clock edge so it's not triggered in the DFF (as you'd have suspected), never mind it'll be caught on the next clock edge.</p> <p>signal in goes low, which triggers an always block, PS is 0 so we set NS to 0. This happens in time for the rising clock edge and is captured in the DFF (argh we missed the NS signal going to 1 as we wanted).</p> <p>Also, someone mentioned that there's an error with your flip-flop being asserted while reset is asserted. This isn't a problem: the reset is synchronous. So on the next rising clock edge the DFF is reset to 0.</p> <p>So, what's the solution (looks like homework to me, so hopefully you've fixed this already!):</p> <p>It should look something like this (I haven't simulated it, so no guarantees):</p> <pre><code>Module UserInput (clk, reset, in, out); input clk, reset, in; output [1:0] out; // output parameters parameter IDLE = 2'b00; parameter DOT = 2'b01; parameter DASH = 2'b10; // FSM states parameter LOW = 3'b000; parameter SHORT1 = 3'b001; parameter SHORT2 = 3'b010; parameter LONG = 3'b100; reg [2:0] state; wire [1:0] next_out; wire [2:0] next_state; always @(posedge clk) begin if (reset) begin out &lt;= IDLE; state &lt;= LOW; end; else begin out &lt;= next_out; state &lt;= next_state; end end if; end always @(*) begin case (state) LOW: next_out = IDLE; next_state = (in? SHORT1 : LOW); SHORT1: begin next_state = (in? SHORT2: LOW); next_out = (in? IDLE : DOT); end; SHORT2: next_state = (in? LONG: LOW); next_out = (in? IDLE : DOT); LONG: next_state = (in? LONG : LOW); next_out = (in? IDLE : DASH); default: // we shouldn't get here!! next_state = LOW; next_out = IDLE; end; end module; </code></pre> <p>So what's going on here: I think this should be fairly obvious. When the in signal moves from high to low then we want to output the current state (LONG as a DASH, SHORT1 and SHORT2 as a DOT), otherwise we output IDLE. If the in signal is high then we want to move the state along depending on how long it's been high for.</p> <p>There's an error with this code which won't effect simulation, but which will almost certainly effect you on the FPGA: if you are getting input from an external source then you'll need to buffer it through a (series?) of flip-flops to prevent metastability problems. This can be fixed by adding a series of D flip-flops to capture the in signal and then passing this "cleaned" buffered_in to the UserInput.</p> <p>ie:</p> <pre><code>module in_buffer (clk, reset, in, out); input clk, reset, in; output out; reg buf1, buf2; always @ (posedge clk) begin if (reset) begin out &lt;= 0; buf1 &lt;= 0; buf2 &lt;= 0; end else out &lt;= buf2; buf2 &lt;= buf1; buf1 &lt;= in; end end </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload