blob: 5c49db9487e561f0c703686890cb85fc7ad84482 (
plain) (
blame)
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
|
`include "defs.svh"
module command_parser
#( TAG = 0
) ( input bit clock
, input bit reset
, output bit uart_ready
, input bit uart_valid
, input uart_byte_t uart_data
, input bit echo_ready
, output bit echo_valid
, output uart_byte_t echo_data
, input bit command_ready
, output bit command_valid
, output ram_command_t command_data
);
bit input_byte_valid;
uart_byte_t input_byte;
(* syn_encoding = "one-hot" *) enum int unsigned
{ READ_ADDRESS_OR_COMMAND
, READ_DATA
} state;
always @(posedge clock) begin
if (reset) begin
uart_ready = 0;
command_valid = 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) begin
command_valid = 0;
command_data.address = 0;
command_data.write = 0;
for (int i = 0; i < `RAM_LINE_WORDS; i = i + 1) begin
command_data.data[i] = 0;
command_data.mask[i] = ~0;
end
command_data.tag = TAG;
end
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_data.address = command_data.address << 4;
command_data.address[$clog2(`RAM_LINE_WORDS)+:4] = input_byte - "0";
end else if (input_byte >= "a" && input_byte <= "f") begin
command_data.address = command_data.address << 4;
command_data.address[$clog2(`RAM_LINE_WORDS)+:4] = input_byte - "a" + 10;
end else if (input_byte >= "A" && input_byte <= "F") begin
command_data.address = command_data.address << 4;
command_data.address[$clog2(`RAM_LINE_WORDS)+:4] = input_byte - "A" + 10;
end else if (input_byte == "?") begin
command_valid = 1;
command_data.write = 0;
command_data.data = 0;
end else if (input_byte == "=") begin
command_data.write = 1;
command_data.data = 0;
state = READ_DATA;
end else begin
command_data.address = 0;
command_data.write = 0;
command_data.data = 0;
end
end
READ_DATA: begin
automatic bit [$bits(command_data.data)-1:0] flat_data = command_data.data;
flat_data = flat_data << 4;
if (input_byte >= "0" && input_byte <= "9") begin
flat_data[3:0] = input_byte - "0";
command_data.data = flat_data;
end else if (input_byte >= "a" && input_byte <= "f") begin
flat_data[3:0] = input_byte - "a" + 10;
command_data.data = flat_data;
end else if (input_byte >= "A" && input_byte <= "F") begin
flat_data[3:0] = input_byte - "A" + 10;
command_data.data = flat_data;
end else begin
command_valid = 1;
state = state.first;
end
end
endcase
input_byte_valid = 0;
end
uart_ready = !echo_valid && !input_byte_valid;
end
end
endmodule
|