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 10

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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