-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlogic_fsm.sv
145 lines (135 loc) · 5.3 KB
/
logic_fsm.sv
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
`define bit_size(x, y) ($clog2((x+y)/2)-1)
`define bit_cells `bit_size(C_NUM_OF_CELLS_X, C_NUM_OF_CELLS_Y)
`define bit_rxy `bit_size(C_CELL_WIDTH, C_CELL_HEIGHT)
module logic_fsm #(
parameter C_NUM_OF_CELLS_X = 5,
parameter C_NUM_OF_CELLS_Y = 5
)(
input iclk,
input istep,
input [`bit_cells:0] line,
input [`bit_cells:0] column,
input istart,
output reg [15:0] oaddr_wr,
output reg owr_en,
output reg [0:0] owr_data,
output reg [15:0] oaddr_rd,
input [0:0] ird_data,
output reg [`bit_cells:0] cur_pos_x,
output reg [`bit_cells:0] cur_pos_y,
output [1:0] odirection
);
typedef enum bit[1:0] {up, down, left, right} direction_t;
typedef enum bit[0:0] {white, black} color_t;
enum bit[3:0] {s0, s1, s2, s3, s4, s5, s6, s7, s8, s9} state;
reg [`bit_cells:0] next_pos_x;
reg [`bit_cells:0] next_pos_y;
direction_t direction, rotation;
color_t cell_color;
assign odirection = direction;
always @(posedge iclk) begin
owr_en <= 0;
case (state)
s0: begin
cur_pos_x <= C_NUM_OF_CELLS_X / 2;
cur_pos_y <= C_NUM_OF_CELLS_Y / 2;
direction <= left;
rotation <= right;
cell_color <= white;
state <= s1; // wait
end
s1: if(istart == 1)
state <= s2; // start
s2: if(istep == 1)
state <= s3;
else
oaddr_rd <= line * C_NUM_OF_CELLS_X + column;
s3: begin
oaddr_rd <= cur_pos_y * C_NUM_OF_CELLS_X + cur_pos_x;
state <= s4;
end
s4: begin
if(ird_data == 1) begin
cell_color <= black;
rotation <= left;
end else begin
cell_color <= white;
rotation <= right;
end
state <= s5;
end
s5: begin
if(rotation == right) begin
case (direction)
up: begin
next_pos_x <= cur_pos_x + 1;
next_pos_y <= cur_pos_y;
direction <= right;
end
down: begin
next_pos_x <= cur_pos_x - 1;
next_pos_y <= cur_pos_y;
direction <= left;
end
left: begin
next_pos_x <= cur_pos_x;
next_pos_y <= cur_pos_y - 1;
direction <= up;
end
right: begin
next_pos_x <= cur_pos_x;
next_pos_y <= cur_pos_y + 1;
direction <= down;
end
endcase
end
if(rotation == left) begin
case (direction)
up: begin
next_pos_x <= cur_pos_x - 1;
next_pos_y <= cur_pos_y;
direction <= left;
end
down: begin
next_pos_x <= cur_pos_x + 1;
next_pos_y <= cur_pos_y;
direction <= right;
end
left: begin
next_pos_x <= cur_pos_x;
next_pos_y <= cur_pos_y + 1;
direction <= down;
end
right: begin
next_pos_x <= cur_pos_x;
next_pos_y <= cur_pos_y - 1;
direction <= up;
end
endcase
end
if(cell_color == white) begin
cell_color <= black;
owr_data <= 1;
end else begin
cell_color <= white;
owr_data <= 0;
end
state <= s6;
end
s6: begin
oaddr_wr <= cur_pos_y * C_NUM_OF_CELLS_X + cur_pos_x;
owr_en <= 1;
state <= s7;
end
s7: begin
cur_pos_x <= next_pos_x;
cur_pos_y <= next_pos_y;
state <= s8;
end
s8: if(istep == 0)
state <= s2;
default:
state <= s0;
endcase
end
endmodule