-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwb_master.sv
145 lines (114 loc) · 2.96 KB
/
wb_master.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
`default_nettype none
module wb_master(
i_rst,
i_clk,
// S100 signals
i_s_out, // sOUT
i_s_inp, // sINP
i_dbin, // pDBIN
i_wr_n, // pWR*
i_addr,
i_do, // CPU -> Device
o_di, // Device -> CPU
o_rdy,
o_xrdy,
o_phantom_n,
o_int_n,
o_hold_n,
// Wishbone Signals
o_wb_cyc,
o_wb_stb,
o_wb_we,
o_wb_addr,
o_wb_data,
i_wb_ack,
i_wb_stall,
i_wb_data,
);
parameter WIDTH = 8;
parameter ADDR_LINES = 16;
localparam DEPTH = 1 << ADDR_LINES;
input wire i_rst;
input wire i_clk;
// S100 Signals
input wire i_s_out;
input wire i_s_inp;
input wire i_dbin;
input wire i_wr_n;
input wire[ADDR_LINES-1:0] i_addr;
input wire[WIDTH-1:0] i_do;
output reg[WIDTH-1:0] o_di;
output wire o_rdy;
output wire o_xrdy;
output reg o_phantom_n = 1, o_int_n = 1, o_hold_n = 1;
// Wishbone Signals
output reg o_wb_cyc;
output reg o_wb_stb;
output reg o_wb_we;
output reg [WIDTH-1:0] o_wb_data;
output reg [ADDR_LINES-1:0] o_wb_addr;
input wire i_wb_ack;
input wire i_wb_stall;
input wire [WIDTH-1:0] i_wb_data;
// wb_master state
localparam STATE_IDLE = 0,
STATE_REQUEST = 1,
STATE_ACK = 2;
reg state = STATE_IDLE;
// Signal to s100 master whether or not the wishbone master/slave
// is still processing a request. Only ready if wb master is in IDLE state
assign o_rdy = state == STATE_IDLE;
assign o_xrdy = state == STATE_IDLE;
// stb is only active while wishbone is processing a request
assign o_wb_stb = state == STATE_REQUEST;
// cyc is held high while request cycle is happening, aka state is not IDLE
assign o_wb_cyc = state != STATE_IDLE;
always @(posedge i_clk) begin
if (i_rst) begin
state = STATE_IDLE;
end
end
always @(posedge i_clk) begin
if (state == STATE_IDLE) begin
// Initiate request if master is not executing output cycle
// and not executing input cycle
if (!i_s_out && !i_s_inp) begin
if (i_dbin) begin
// Read request
o_wb_we <= 1'b0;
o_wb_addr <= i_addr;
end else if (!i_wr_n) begin
// Write request
o_wb_we <= 1'b1;
o_wb_data <= i_do;
o_wb_addr <= i_addr;
end
if (i_dbin || !i_wr_n) begin
// If write or read request, transition to REQUEST state
state <= STATE_REQUEST;
end
end
end else if (state == STATE_REQUEST) begin
if (!i_wb_stall) begin
state <= STATE_ACK;
// Handle case where slave device acks in the same cycle of ending stall
if (i_wb_ack) begin
// If request was a write, update data input on the s100 bus
if (!o_wb_we) begin
o_di <= o_wb_data;
end
state <= STATE_IDLE;
end
end
end else if (state == STATE_ACK) begin
// Wait until wishbone slave acks
if (i_wb_ack) begin
// If request was a write, update data input on the s100 bus
if (!o_wb_we) begin
o_di <= o_wb_data;
end
state <= STATE_IDLE;
end
end
end
endmodule