1 //////////////////////////////////////////////////////////////////////
6 //// This file is part of the CAN Protocol Controller ////
7 //// http://www.opencores.org/projects/can/ ////
12 //// igorm@opencores.org ////
15 //// All additional information is available in the README.txt ////
18 //////////////////////////////////////////////////////////////////////
20 //// Copyright (C) 2002, 2003, 2004 Authors ////
22 //// This source file may be used and distributed without ////
23 //// restriction provided that this copyright statement is not ////
24 //// removed from the file and that any derivative work contains ////
25 //// the original copyright notice and the associated disclaimer. ////
27 //// This source file is free software; you can redistribute it ////
28 //// and/or modify it under the terms of the GNU Lesser General ////
29 //// Public License as published by the Free Software Foundation; ////
30 //// either version 2.1 of the License, or (at your option) any ////
31 //// later version. ////
33 //// This source is distributed in the hope that it will be ////
34 //// useful, but WITHOUT ANY WARRANTY; without even the implied ////
35 //// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
36 //// PURPOSE. See the GNU Lesser General Public License for more ////
39 //// You should have received a copy of the GNU Lesser General ////
40 //// Public License along with this source; if not, download it ////
41 //// from http://www.opencores.org/lgpl.shtml ////
43 //// The CAN protocol is developed by Robert Bosch GmbH and ////
44 //// protected by patents. Anybody who wants to implement this ////
45 //// CAN IP core on silicon has to obtain a CAN protocol license ////
48 //////////////////////////////////////////////////////////////////////
50 // synopsys translate_off
51 `include "timescale.v"
52 // synopsys translate_on
53 `include "can_defines.v"
68 assign reg_cs_o = oreq != req_i;
70 always @(posedge clk_i or negedge rstn_i)
79 // we is already set from axi side and is stable
80 // data_in is already set from axi side and is stable
81 // data_out is set from reg in this cycle
91 // Width of S_AXI data bus
92 parameter integer C_S_AXI_DATA_WIDTH = 32,
93 // Width of S_AXI address bus
94 parameter integer C_S_AXI_ADDR_WIDTH = 8
98 output wire reg_rst_o,
100 output wire reg_we_o,
101 output wire [7:0] reg_addr_o,
102 output wire [7:0] reg_data_in_o,
103 input wire [7:0] reg_data_out_i,
105 input wire S_AXI_ACLK,
106 input wire S_AXI_ARESETN,
108 input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_AWADDR,
109 input wire [2:0] S_AXI_AWPROT,
110 input wire S_AXI_AWVALID,
111 output reg S_AXI_AWREADY,
113 input wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_WDATA,
114 input wire [(C_S_AXI_DATA_WIDTH/8)-1 : 0] S_AXI_WSTRB,
115 input wire S_AXI_WVALID,
116 output reg S_AXI_WREADY,
118 output reg [1:0] S_AXI_BRESP,
119 output reg S_AXI_BVALID,
120 input wire S_AXI_BREADY,
122 input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_ARADDR,
123 input wire [2:0] S_AXI_ARPROT,
124 input wire S_AXI_ARVALID,
125 output reg S_AXI_ARREADY,
127 output wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_RDATA, // TODO: reg
128 output reg [1:0] S_AXI_RRESP,
129 output reg S_AXI_RVALID,
130 input wire S_AXI_RREADY
139 output [7:0] reg_data_in_o;
140 input [7:0] reg_data_out_i;
149 reg [1:0] ready_read_hist;
150 reg [1:0] ready_write_hist;
151 wire ready_read_edge;
152 wire ready_write_edge;
153 assign ready_read_edge = ready_read_hist[0] ^ ready_read_hist[1];
154 assign ready_write_edge = ready_write_hist[0] ^ ready_write_hist[1];
159 reg read_active_edge;
160 reg write_active_edge;
166 assign read_finished = S_AXI_RVALID;
167 assign write_finished = S_AXI_BVALID;
169 // read/write arbitration
170 always @ (posedge S_AXI_ACLK or negedge S_AXI_RST)
174 write_pending <= 1'b0;
175 write_active <= 1'b0;
176 read_pending <= 1'b0;
178 ready_read_hist <= 2'b00;
179 ready_write_hist <= 2'b00;
183 ready_read_hist <= {ready_read_hist[0], S_AXI_ARVALID};
184 ready_write_hist <= {ready_write_hist[0], S_AXI_AWVALID & S_AXI_WVALID /*& (S_AXI_WSTRB == 4'b1111)*/};
187 if(S_AXI_AWVALID & S_AXI_WVALID & (S_AXI_WSTRB != 4'b1111))
194 if (write_active_edge)
195 write_active_edge = 0;
196 if (read_active_edge)
197 read_active_edge = 0;
199 if (ready_write_edge)
201 if (read_active & ~read_finished)
206 write_active_edge = 1;
212 if (write_active & ~write_finished)
217 read_active_edge = 1;
221 // read finished in previous cycle
232 // write finished in previous cycle
235 write_active <= 1'b0;
245 //assign reg_addr_o <= write ? axi_waddr : axi_raddr;
246 // assign reg_addr_o - asynchronous, synchronized by protocols expectations
247 // should not synthesise any regs or latches
248 assign reg_addr_o = write_active ? S_AXI_AWADDR :
249 read_active ? S_AXI_ARADDR :
253 // latch read response data
254 always @(posedge S_AXI_ACLK)
257 latched_data <= reg_data_out_i;
261 always @(negedge S_AXI_RST or posedge S_AXI_ACLK)
266 //S_AXI_RDATA <=#C_S_AXI_DATA_WIDTH 0;
268 S_AXI_BVALID <= 1'b0;
269 S_AXI_WREADY <= 1'b0;
270 S_AXI_AWREADY <= 1'b0;
273 // no synchronization necessary
274 if (read_active_edge | write_active_edge)
280 //S_AXI_RDATA <= reg_data_out_i; // TODO: should be allright, the address is stable ...
281 // read_active will be deasserted after asserting S_AXI_RVALID, so this will execute only 2x
282 S_AXI_RVALID <= ~S_AXI_RVALID;
283 S_AXI_ARREADY <= ~S_AXI_ARREADY;
284 end else if (write_active)
286 S_AXI_BRESP <= 2'b00; // TODO: value?
287 // write_active will be deasserted after asserting S_AXI_RVALID, so this will execute only 2x
288 S_AXI_BVALID <= ~S_AXI_BVALID;
289 S_AXI_WREADY <= ~S_AXI_WREADY;
290 S_AXI_AWREADY <= ~S_AXI_AWREADY;
297 assign reg_rst_o = ~S_AXI_RST;
298 assign reg_we_o = write_active;
299 assign reg_addr_o = S_AXI_AWADDR; // TODO: latch?
300 assign reg_data_in_o = S_AXI_WDATA;
301 assign S_AXI_RDATA = reg_data_out_i; // TODO: latch?
303 can_ifc_async CAN_IFC_ASYNC