onehot.v.txt
上传用户:saul_905
上传日期:2013-11-27
资源大小:184k
文件大小:6k
源码类别:

VHDL/FPGA/Verilog

开发平台:

Visual C++

  1. // 
  2. // Just a little demo of some FSM techniques, including One-Hot and
  3. // using 'default' settings and the case statements to selectively
  4. // update registers (sort of like J-K flip-flops).
  5. //
  6. // tom coonan, 12/98.
  7. //
  8. module onehot (clk, resetb, a, b, x, y);
  9. input clk;
  10. input resetb;
  11. input [7:0] a;
  12. input [7:0] b;
  13. output [7:0] x;
  14. output [7:0] y;
  15. // Use One-Hot encoding.  There will be 16 states.
  16. //
  17. reg [15:0] state, next_state;
  18. // These are working registers.  Declare the register itself (e.g. 'x') and then
  19. // the input bus used to load in a new value (e.g. 'x_in').  The 'x_in' bus will
  20. // physically be a wire bus and 'x' will be the flip-flop register ('x_in' must
  21. // be declared 'reg' because it's used in an always block.
  22. //
  23. reg [7:0] x, x_in;
  24. reg [7:0] y, y_in;
  25. // Update state.  'state' is the actual flip-flop register and next_state is the combinatorial
  26. // bus used to update 'state''s value.  Check for the ZERO state which means an unexpected
  27. // next state was computed.  If this occurs, jump to our initialization state; state[0].
  28. // 
  29. // It is considered good practice by many designers to seperate the combinatorial
  30. // and sequential aspects of state registers, and often registers in general.
  31. //
  32. always @(posedge clk or negedge resetb) begin
  33.    if (~resetb) state <= 0;
  34.    else begin
  35.       if (next_state == 0) begin
  36.          state <= 16'h0001;
  37.       end
  38.       else begin
  39.          state <= next_state;
  40.       end
  41.    end
  42. end
  43. // Implement the X flip-flop register.  Always load the input bus into the register.
  44. // Reset to zero.
  45. //
  46. always @(posedge clk or negedge resetb) begin
  47.    if (~resetb) x <= 0;
  48.    else         x <= x_in;
  49. end
  50. // Implement the Y flip-flop register.  Always load the input bus into the register.
  51. // Reset to zero.
  52. //
  53. always @(posedge clk or negedge resetb) begin
  54.    if (~resetb) y <= 0;
  55.    else         y <= y_in;
  56. end
  57. // Generate the next_state function.  Also, based on the current state, generate
  58. // any new values for X and Y.
  59. //
  60. always @(state or a or b or x or y) begin
  61.    // *** Establish defaults.
  62.    
  63.    // Working registers by default retain their current value.  If any particular
  64.    // state does NOT need to change a register, then it doesn't have to reference
  65.    // the register at all.  In these cases, the default below takes affect.  This
  66.    // turns out to be a pretty succinct way to control stuff from the FSM.
  67.    //
  68.    x_in <= x;
  69.    y_in <= y;
  70.    
  71.    // State by default will be cleared.  If we somehow ever got into an unknown
  72.    // state, then the default would throw state machine back to zero.  Look
  73.    // at the sequential 'always' block for state to see how this is handled.
  74.    //
  75.    next_state <= 0;
  76.    
  77.    // One-Hot State Machine Encoding.
  78.    //
  79.    // *** Using a 1'b1 in the case statement is the trick to doing One-Hot...
  80.    //     DON'T include a 'default' clause within the case because we want to
  81.    //     establish the defaults above. ***
  82.    //
  83.    case (1'b1) // synopsys parallel_case
  84.    
  85.       // Initialization state.  Set X and Y register to some interesting starting values.
  86.       //
  87.       state[0]:
  88.          begin
  89.             x_in <= 8'd20;
  90.             y_in <= 8'd100;
  91.             next_state[1] <= 1'b1;
  92.          end
  93.       
  94.       // Just for fun.. Jump through states..  
  95.       state[1]: next_state[2] <= 1'b1;
  96.       state[2]: next_state[3] <= 1'b1;
  97.       state[3]: next_state[4] <= 1'b1;
  98.       state[4]: next_state[5] <= 1'b1;
  99.       state[5]: next_state[6] <= 1'b1;
  100.       state[6]: next_state[7] <= 1'b1;
  101.       
  102.       // Conditionally decrement Y register.
  103.       state[7]:
  104.          begin
  105.             if (a == 1) begin
  106.                y_in <= y - 1;
  107.                next_state[1] <= 1'b1;
  108.             end
  109.             else begin
  110.                next_state[8] <= 1'b1;
  111.             end
  112.          end
  113.         
  114.       // Just for fun.. Jump through states..  
  115.       state[8]: next_state[9]   <= 1'b1;
  116.       state[9]: next_state[10]  <= 1'b1;
  117.       state[10]: next_state[11] <= 1'b1;
  118.       // Conditionally increment X register.
  119.       state[11]:
  120.          begin
  121.             if (b == 1) begin
  122.                x_in <= x + 1;
  123.                next_state[1] <= 1'b1;
  124.             end
  125.             else begin
  126.                next_state[12] <= 1'b1;
  127.             end
  128.          end
  129.       // Just for fun.. Jump through states..  
  130.       state[12]: next_state[13] <= 1'b1;
  131.       state[13]: next_state[14] <= 1'b1;
  132.       state[14]: next_state[15] <= 1'b1;
  133.       state[15]: next_state[1]  <= 1'b1; // Don't go back to our initialization state, but state following that one.
  134.     endcase
  135. end
  136. endmodule
  137. // synopsys translate_off
  138. module test_onehot;
  139. reg clk, resetb;
  140. reg [7:0] a;
  141. reg [7:0] b;
  142. wire [7:0] x;
  143. wire [7:0] y;
  144. // Instantiate module.
  145. //
  146. onehot onehot (
  147.    .clk(clk),
  148.    .resetb(resetb),
  149.    .a(a),
  150.    .b(b),
  151.    .x(x),
  152.    .y(y)
  153. );
  154. // Generate clock.
  155. //
  156. initial begin
  157.    clk = 0;
  158.    forever begin
  159.       #10 clk = ~clk;
  160.    end
  161. end
  162. // Reset..
  163. //
  164. initial begin
  165.    resetb = 0;
  166.    #33 resetb = 1;
  167. end
  168. // Here's the test.
  169. //
  170. // Should see X and Y get initially loaded with their starting values.
  171. // As long as a and b are zero, nothing should change.
  172. // When a is asserted, Y should slowly decrement.  When b is asserted, X should
  173. // slowly increment.  That's it.
  174. //
  175. initial begin 
  176.    a = 0;
  177.    b = 0;
  178.    repeat (64) @(posedge clk);
  179.    #1
  180.    
  181.    // Y should be decremented..
  182.    a = 1;
  183.    b = 0;
  184.    repeat (256) @(posedge clk);
  185.    #1
  186.    
  187.    // X should be incremented..
  188.    a = 0;
  189.    b = 1;
  190.    repeat (256) @(posedge clk);
  191.    
  192.    $finish;
  193. end
  194. // Monitor the module.
  195. //
  196. initial begin
  197.    forever begin
  198.       @(posedge clk);
  199.       #1;
  200.       $display ("a = %b, b = %b, x = %0d, y = %0d", a,b,x,y);
  201.    end
  202. end
  203.       
  204. endmodule