// Module master_control. Toggles the output go based on the input button. module master_control( clk, // Input for our clock en, // enable for the master_control state machine r, // reset for the master_control state machine button, // the input for the button which will toggle go // the output saying if we are good to go or locked ); // *** INPUTS *** input clk, en, r; input button; // *** OUTPUTS *** output go; // Since we will assign a value to 'go' using combinational logic it // also needs to be a reg. Notice how 'go' is assigned below in the // NEXT STATE LOGIC based on the combinational value of the state. // If you don't do this you will get a cryptic error message when you // try to synthesize. reg go; // *** STATES *** // Define our states for easy reading. These are just like #define in // C/C++. If you forget and put a ; after the 1'b0 you will find that // the tools insert that below in your code where ever you use `STOP // or `GO and you will get error messages. `define STOP 1'b0 `define GO 1'b1 // *** WIRES *** // This is a wire because it is just sending the output // of the state FFs to the state machine. wire current_state_q; // This is a reg because we want to assign its value with // the combinational logic in the NEXT STATE LOGIC. reg next_state_d; // Both the current_state_q and the next_state_d connect to the state // FFs defined at the bottom. Note that the _d and _q suffixes help // use keep track of which is which. Since the output from the state // FFs is just sent into the combination logic (see the diagram in the // tutorial) and is not changed (it can't be--why?--because then the // value in the FF would have to change and that can only be done with // the input) it should be a wire. The input to the FFs (next_state_d) // does get changed by the combinational logic and therefore needs to // be a reg. // *** NEXT STATE LOGIC *** // Here is our next-state combinational logic. Note that it can change // any time current_state_q or button changes, so they must appear in // the sensetivity list. Basically anything that is on the right-hand // side of an expression or in an if() or case() statement must appear // in the sensetivity list. The tools should complain if you don't // include everything you need, but they may not. Simulations may be // slower if you include too much, though. // Sensetivity list always @(current_state_q or button) begin // Case statement to do different things based on the state case(current_state_q) // If we are in the STOP state then we want to have the output // 'go' be false. If the button is pressed then our next state // will be GO and otherwise our next state will be STOP. `STOP: begin go = 1'b0; if (button) begin next_state_d = `GO; end else begin next_state_d = `STOP; end end // If we are in the GO state then we want to have the output // 'go' be true. If the button is pressed then our next state // will be STOP and otherwise our next state will be GO. `GO: begin go = 1'b1; if (button) begin next_state_d = `STOP; end else begin next_state_d = `GO; end end // It is always important to have a default case in here so // you don't end up infering logic. This is particularly true // with one-hot encoding. For now just trust us on this and always // include a default case. (We will be checking.) default: begin go = 1'b0; next_state_d = `STOP; end // End of the case statement endcase // End of the combinational logic for the next state end // *** STATE REGISTERS *** // Here is one flip flop from the EE183 FF library with an enable and a // reset. These are passed up to the FSM's own enable and reset so we // get those functions for free this way. Note that the .q output is // wired to the current_state_q and the input is the reg next_state_d // which is defined in the combinational logic above. dffre state_ff(.clk(clk), .en(en), .r(r), .d(next_state_d), .q(current_state_q)); endmodule