-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdbg_uart.v
96 lines (92 loc) · 2.24 KB
/
dbg_uart.v
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
/*
* $Id$
*
* Debugger memory access using the UART
*
* Commands are letters:
*
* i - read status, response is one status byte
* a - address, followed by two bytes, big endian
* w - write data, followed by one byte data, addr++
* W - write data, followed by two bytes data, addr+=2
* r - read data, response is one byte data, addr++
* l - transfer low byte, respones is one byte data, addr++ (no read access)
*
* axxrl reads a word with a single access (necessary e.g. for the stack window)
*
* Communication must start with either i or a, for baut rate detection
*/
module dbg_uart(clk, nreset, dix, dox, id, od,
csu, addru, ru, wru, data, datau, status, state);
input clk, nreset, dix;
input [7:0] id, status;
input [15:0] data;
output dox, csu, ru;
output [7:0] od;
output [15:0] addru, datau;
output [1:0] wru;
output [2:0] state;
reg dox, ru;
reg [2:0] state;
reg [7:0] od, lowbyte;
reg [15:0] addru, datau;
reg [1:0] wru;
wire csu = |{wru, ru};
always @(posedge clk or negedge nreset)
if(!nreset) begin
dox <= 0;
ru <= 0;
wru <= 0;
addru <= 0;
datau <= 0;
lowbyte <= 0;
od <= 0;
end else begin
dox <= 0;
if(csu & status[1]) begin
addru <= addru + ru + wru[0] + wru[1];
ru <= 0;
wru <= 0;
if(ru) begin
{ dox, od } <= { 1'b1, ~addru[0] ? data[15:8] : data[7:0] };
lowbyte <= data[7:0];
end
end else if(dix) begin
case(state)
3'b000: case(id)
"a": state <= 2;
"i": { dox, od } <= { 1'b1, status };
"w": state <= 1;
"W": state <= 4;
"r": ru <= 1;
"l": { addru, dox, od } <= { addru + 1, 1'b1, lowbyte };
default: state <= 0;
endcase // casez (id)
3'b001: begin
datau <= { id, id };
wru <= addru[0] ? 2'b01 : 2'b10;
state <= 0;
end
3'b010: begin
addru[15:8] <= id;
state <= 3;
end
3'b011: begin
addru[7:0] <= id;
state <= 0;
end
3'b100: begin
datau[15:8] <= id;
state <= 5;
end
3'b101: begin
datau[7:0] <= id;
wru <= 2'b11;
state <= 0;
end
3'b110: state <= 0;
3'b111: state <= 0;
endcase // case (state)
end // if (dix)
end // else: !if(!nreset)
endmodule // dbg_uart