OpenCores
URL https://opencores.org/ocsvn/ssbcc/ssbcc/trunk

Subversion Repositories ssbcc

[/] [ssbcc/] [trunk/] [core/] [9x8/] [peripherals/] [AXI4_Lite_Master.v] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 sinclairrf
//
2
// PERIPHERAL:  AXI4-Lite Master
3
//
4
generate
5
localparam L__ADDRESS_WIDTH = @ADDRESS_WIDTH@;
6
localparam L__ISSYNC = @ISSYNC@;
7
localparam L__RESP_OKAY = 2'b00;
8
// Shift 8-bit values into the output 32-bit word.
9
initial o_wdata = 32'd0;
10
always @ (posedge i_clk)
11
  if (i_rst)
12
    o_wdata <= 32'd0;
13
  else if (s_outport && (s_T == 8'd@IX_DATA@))
14
    o_wdata <= { o_wdata[0+:24], s_N };
15
  else
16
    o_wdata <= o_wdata;
17
// Shift 8-bit values into the common output address and coerce 2 lsb of output
18
// addresses to 0.
19
reg [L__ADDRESS_WIDTH-1:0] s__addr = @ADDRESS_WIDTH@'d0;
20
if (L__ADDRESS_WIDTH <= 8) begin : gen__short_addr
21
  always @ (posedge i_clk)
22
    if (i_rst)
23
      s__addr <= @ADDRESS_WIDTH@'d0;
24
    else if (s_outport && (s_T == 8'd@IX_ADDRESS@))
25
      s__addr <= s_N[0+:L__ADDRESS_WIDTH];
26
    else
27
      s__addr <= s__addr;
28
end else begin : gen__long_addr
29
  always @ (posedge i_clk)
30
    if (i_rst)
31
      s__addr <= @ADDRESS_WIDTH@'d0;
32
    else if (s_outport && (s_T == 8'd@IX_ADDRESS@))
33
      s__addr <= { s__addr[L__ADDRESS_WIDTH-9:0], s_N };
34
    else
35
      s__addr <= s__addr;
36
end
37
always @ (*) begin
38
  o_awaddr <= { s__addr[L__ADDRESS_WIDTH-1:2], 2'b00 };
39
  o_araddr <= { s__addr[L__ADDRESS_WIDTH-1:2], 2'b00 };
40
end
41
// Either use the raw write strobe or synchronize the write strobe.
42
wire s__wr_aclk;
43
if (L__ISSYNC) begin : gen__sync_wr
44
  assign s__wr_aclk = s__wr;
45
end else begin : gen__async_wr
46
  reg s__wr_toggle = 1'b0;
47
  always @ (posedge i_clk)
48
    s__wr_toggle <= s__wr ^ s__wr_toggle;
49
  reg [3:0] s__wr_s = 4'd0;
50
  always @ (i_aclk)
51
    s__wr_s <= { s__wr_s[0+:3], s__wr_toggle };
52
  reg s__wr_aclk_out = 1'b0;
53
  always @ (posedge i_aclk)
54
    s__wr_aclk_out <= ^s__wr_s[2+:2];
55
  assign s__wr_aclk = s__wr_aclk_out;
56
end
57
// Write side of the bus.
58
initial o_awvalid = 1'b0;
59
initial o_wvalid  = 1'b0;
60
initial o_bready  = 1'b0;
61
reg [2:0] s__pending_wr = 3'h0;
62
always @ (posedge i_aclk)
63
  if (~i_aresetn) begin
64
    o_awvalid <= 1'b0;
65
    o_wvalid  <= 1'b0;
66
    o_bready  <= 1'b0;
67
    s__pending_wr <= 3'h0;
68
  end else begin
69
    o_awvalid <= o_awvalid;
70
    o_wvalid  <= o_wvalid;
71
    o_bready  <= o_bready;
72
    s__pending_wr <= s__pending_wr;
73
    if (s__wr_aclk) begin
74
      o_awvalid <= 1'b1;
75
      o_wvalid  <= 1'b1;
76
      o_bready  <= 1'b0;
77
      s__pending_wr <= 3'b111;
78
    end else begin
79
      if (i_awready) begin
80
        o_awvalid <= 1'b0;
81
        s__pending_wr[0] <= 1'b0;
82
      end
83
      if (i_wready) begin
84
        o_wvalid <= 1'b0;
85
        s__pending_wr[1] <= 1'b0;
86
      end
87
      if (i_bvalid) begin
88
        if (!o_bready)
89
          o_bready <= 1'b1;
90
        else begin
91
          o_bready <= 1'b0;
92
          s__pending_wr[2] <= 1'b0;
93
        end
94
      end
95
    end
96
  end
97
 
98
// Either use the raw read strobe or synchronize the read strobe.
99
wire s__rd_aclk;
100
if (L__ISSYNC) begin : gen__sync_rd
101
  assign s__rd_aclk = s__rd;
102
end else begin : gen__async_rd
103
  reg s__rd_toggle = 1'b0;
104
  always @ (posedge i_clk)
105
    s__rd_toggle <= s__rd ^ s__rd_toggle;
106
  reg [3:0] s__rd_s = 4'd0;
107
  always @ (i_aclk)
108
    s__rd_s <= { s__rd_s[0+:3], s__rd_toggle };
109
  reg s__rd_aclk_out = 1'b0;
110
  always @ (posedge i_aclk)
111
    s__rd_aclk_out <= ^s__rd_s[2+:2];
112
  assign s__rd_aclk = s__rd_aclk_out;
113
end
114
 
115
// Generate the read address valid signal and record the address acknowledgement
116
// pending status.
117
reg s__pending_rd_aclk = 1'b0;
118
always @ (posedge i_aclk)
119
  if (~i_aresetn) begin
120
    o_arvalid <= 1'b0;
121
    s__pending_rd_aclk <= 1'b0;
122
  end else if (s__rd_aclk) begin
123
    o_arvalid <= 1'b1;
124
    s__pending_rd_aclk <= 1'b1;
125
  end else if (i_arready) begin
126
    o_arvalid <= 1'b0;
127
    s__pending_rd_aclk <= 1'b0;
128
  end else begin
129
    o_arvalid <= o_arvalid;
130
    s__pending_rd_aclk <= s__pending_rd_aclk;
131
  end
132
 
133
// Generate a strobe from the i_aclk domain to the i_clk domain to latch the
134
// incoming read data and then generate a strobe in the reverse direction to
135
// acknowledge the data.
136
wire s__latch_read;
137
if (L__ISSYNC) begin : gen__sync_read_ack
138
  always @ (posedge i_aclk)
139
    if (~i_aresetn)
140
      o_rready <= 1'b0;
141
    else
142
      o_rready <= i_rvalid && ~o_rready;
143
  assign s__latch_read = o_rready;
144
end else begin : gen__async_read_ack
145
  reg s__rvalid_toggle = 1'b0;
146
  always @ (i_aclk)
147
    if (~i_aresetn)
148
      s__rvalid_toggle <= 1'b0;
149
    else if (s__rd_aclk)
150
      s__rvalid_toggle <= 1'b0;
151
    else if (i_rvalid)
152
      s__rvalid_toggle <= 1'b1;
153
    else
154
      s__rvalid_toggle <= s__rvalid_toggle;
155
  reg [3:0] s__rvalid_toggle_s = 4'd0;
156
  always @ (posedge i_clk)
157
    s__rvalid_toggle_s <= { s__rvalid_toggle_s[0+:2], s__rvalid_toggle };
158
  reg s__latch_read_p = 1'b0;
159
  always @ (posedge i_clk)
160
    if (i_rst)
161
      s__latch_read_p <= 1'b0;
162
    else
163
      s__latch_read_p <= (s__rvalid_toggle_s[2+:2] == 2'b01);
164
  assign s__latch_read = s__latch_read_p;
165
  reg s__latch_toggle = 1'b0;
166
  always @ (posedge i_clk)
167
    if (i_rst)
168
      s__latch_toggle <= 1'b0;
169
    else if (s__rd)
170
      s__latch_toggle <= 1'b0;
171
    else if (s__latch_read_p)
172
      s__latch_toggle <= 1'b1;
173
    else
174
      s__latch_toggle <= s__latch_toggle;
175
  reg [3:0] s__latch_toggle_s = 4'd0;
176
  always @ (posedge i_aclk)
177
    s__latch_toggle_s <= { s__latch_toggle_s[0+:3], s__latch_toggle };
178
  always @ (posedge i_aclk)
179
    if (~i_aresetn)
180
      o_rready <= 1'b0;
181
    else if (s__rd_aclk)
182
      o_rready <= 1'b0;
183
    else
184
      o_rready <= (s__latch_toggle_s[2+:2] == 2'b01);
185
end
186
 
187
// Track the "pending" status of the data acknowledgement.
188
reg s__pending_rd_clk = 1'b0;
189
always @ (posedge i_clk)
190
  if (i_rst)
191
    s__pending_rd_clk <= 1'b0;
192
  else if (s__rd)
193
    s__pending_rd_clk <= 1'b1;
194
  else if (s__latch_read)
195
    s__pending_rd_clk <= 1'b0;
196
  else
197
    s__pending_rd_clk <= s__pending_rd_clk;
198
 
199
// Store the received value in a 32-bit word and right shift it when it's read.
200
always @ (posedge i_clk)
201
  if (i_rst)
202
    s__read <= 32'd0;
203
  else if (s__latch_read)
204
    s__read <= i_rdata;
205
  else if (s_inport && (s_T == 8'd@IX_READ@))
206
    s__read <= { 8'd0, s__read[8+:24] };
207
 
208
// Composite status (non-zero indicates the bus has not finished the last
209
// transaction).
210
always @ (posedge i_clk)
211
  s__busy <= { s__pending_rd_clk, s__pending_rd_aclk, s__pending_wr };
212
 
213
// Monitor the bresp and rresp 2-bit signals for non-OK indication
214
always @ (posedge i_aclk)
215
  if (~i_aresetn)
216
    s__error <= 2'd0;
217
  else begin
218
    if (i_bvalid && o_bready) s__error[0] <= (i_bresp != L__RESP_OKAY);
219
    if (i_rvalid && o_rready) s__error[1] <= (i_rresp != L__RESP_OKAY);
220
  end
221
 
222
endgenerate

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.