summaryrefslogtreecommitdiff
path: root/20.md
blob: 0d30c32aea99c137ca20abf72561993d862c86ec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
[\<- Multiple control outputs](19.md)

---

# 1-hot encoding and State machines in Verilog

## 1-hot encoding

- Requires more flops, one for each state
- Next state and output equations can be more directly identified
- One-hot version of example 1:
	- `Y1 = !w`, `Y2 = w*y1`, `Y3 = w*(y3+y2)`, `z = y3`

![diagram](20.1.png)

- Number of bits = number of unique states

### One-Hot Version of Example 2

- K-map would be 5 variable, or just
	- `Y4 = y3`
	- `Y3 = y2`
	- `Y2 = w*y1`
	- `Y1 = y4+!w*y1`
	- `R1out = R2 = y3`
	- `R1in = R3out = Done = y4`
	- `R2out = R3in = y2`

![diagram](20.2.png)

---

## Structuring Verilog for a state machine

- Combinational logic to
	- generate "next" value as a function fo "current" value and inputs
	- generate outputs
- Flip-flops update "current" value with "next"

![diagram](20.3.png)

### Variable declarations

- The inputs, outputs, and clock will already be covered by the interface definition
- Need variables for current state and next state
	- Current state needs to be type "reg"
	- If we describe next state logic in an always block, also needs to be type "reg"
- Need to know how many bits, to accommodate state assignments
	- `reg [1:0] cState, nState; // defines 2-bit state`

---

## Writing code for the "next state" logic

### Structuring state updates

- Useful to separate flops (i.e., state) from combinational logic that generates next state
	- Flops under `always @(posedge clk)`
- Next state equations can be translated into code, either `assign` or `always @(*)`
- Or, use a case statement (inside always)
	- For each case/state, determine next state as a function of control inputs

### Case statement for example 1

- Assuming state assignments 00, 01, 10

```
always @(*)
	case(cState)
		2'b00: if(w) nState=2'b01; else nState=2'b00;
		2'b01: if(w) nState=2'b10; else nState=2'b00;
		2'b10: if(w) nState=2'b10; else nState=2'b00;
		default: nState=2'b00;
	endcase
```

![diagram](20.4.png)

---

## Other pieces: output logic, reset, and the parameter statement

### Output logic

- In this state machine, just a single output (z), which asserts when we're in state C
- A simple assign statement will do the trick:
	- `assign z = cState[1] & !cState[0];`
	- or `assign z = (cState == 2'b10);`

### Resetting the state machine

- Note the circular dependence in a sequential desing:
	- `nState = f(cState)`, `cState=f(nState)`
- When we "start", we don't know cState
- A reset signal forces a known state
	- Can be synchronous or asynchronous

```
always @(posedge clock)
	if(reset) cState = 2'b00;
	else cState = nState;
```

### Giving names to states

- State variables are necessarily binary values, but giving names to states makes code easier to write and follow
- Parameter statement associates names (text) with state assignments
	- Parameter [1:0] StateA=2'b00, StateB=2'b01, StateC=2'b10;
- Note that the "width" needs to match the width of the state varaibles (cState and nState)

---

## Putting it all together: the full sequence detector module

### Sequence detector

```
module simple(Clock, Resetn, w, z);
	input Clock, Resetn, w;
	output z;
	reg [2:1] y, Y;
	parameter [2:1] A = 2'b00, B = 2'b01, C = 2'b10;

	// Define the next state combinational circuit
	always @(w, y)
		case(y)
			A: if(w) Y = B;
			  else Y = A;
			B: if(w) Y = C;
			  else Y = A;
			C: if(w) Y = C;
			  else Y = A;
			default: Y = 2'bxx;
		endcase

	// Define the sequential block
	always @(negedge Resetn, posedge Clock)
		if(Resetn == 0) y <= A;
		else y <= Y;

	// Define output
	assign z = (y == C);

endmodule
```

---

## Changing state assignments

- Another value proposition of using parameter statement is ease of changing state assignments
- Switching to 1-hot for this design would simply involve changing 2 lines:

```
reg [2:0] y, Y;
parameter [2:0] A=3'b001, B=3'b010, C=3'b100;
```

---

[Multiple control inputs ->](21.md)