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
|
module command_parser
( input bit clock
, input bit resetn
, output bit uart_ready
, input bit uart_valid
, input bit [7:0] uart_data
, input bit echo_ready
, output bit echo_valid
, output bit [7:0] echo_data
, input bit command_ready
, output bit command_valid
, output bit [23:0] command_address
, output bit command_write
, output bit [15:0] command_data
);
bit input_byte_valid;
bit [7:0] input_byte;
(* syn_encoding = "one-hot" *) enum
{ READ_ADDRESS_OR_COMMAND
, READ_DATA_1
, READ_DATA_2
, READ_DATA_3
, READ_DATA_4
} state;
always @(posedge clock) begin
if (!resetn) begin
uart_ready = 0;
command_valid = 0;
command_address = 0;
command_write = 0;
command_data = 0;
input_byte_valid = 0;
input_byte = 0;
state = state.first;
end else begin
if (echo_ready) echo_valid = 0;
if (command_ready) command_valid = 0;
if (uart_ready && uart_valid) begin
echo_valid = 1;
echo_data = uart_data;
input_byte_valid = 1;
input_byte = uart_data;
end
if (!command_valid && input_byte_valid) begin
case (state)
READ_ADDRESS_OR_COMMAND: begin
if (input_byte >= "0" && input_byte <= "9") begin
command_address = command_address << 4;
command_address[3:0] = input_byte - "0";
end else if (input_byte >= "a" && input_byte <= "f") begin
command_address = command_address << 4;
command_address[3:0] = input_byte - "a" + 10;
end else if (input_byte >= "A" && input_byte <= "F") begin
command_address = command_address << 4;
command_address[3:0] = input_byte - "A" + 10;
end else if (input_byte == "?") begin
command_valid = 1;
command_write = 0;
command_data = 0;
end else if (input_byte == "=") begin
command_write = 1;
command_data = 0;
state = READ_DATA_1;
end
end
READ_DATA_1, READ_DATA_2, READ_DATA_3, READ_DATA_4: begin
if (input_byte >= "0" && input_byte <= "9") begin
command_data = command_data << 4;
command_data[3:0] = input_byte - "0";
state = state.next;
end else if (input_byte >= "a" && input_byte <= "f") begin
command_data = command_data << 4;
command_data[3:0] = input_byte - "a" + 10;
state = state.next;
end else if (input_byte >= "A" && input_byte <= "F") begin
command_data = command_data << 4;
command_data[3:0] = input_byte - "A" + 10;
state = state.next;
end else begin
state = state.first;
end
command_valid = state == state.first;
end
endcase
input_byte_valid = 0;
end
uart_ready = !echo_valid && !input_byte_valid;
end
end
endmodule
|