]> rtime.felk.cvut.cz Git - fpga/zynq/canbench-sw.git/blob - system/ip/can_crossbar_1.0/hdl/can_crossbar_v1_0_S00_AXI.v
6e04630edf1e3d13db4c10cf98d0eba8fe0fb63e
[fpga/zynq/canbench-sw.git] / system / ip / can_crossbar_1.0 / hdl / can_crossbar_v1_0_S00_AXI.v
1
2 `timescale 1 ns / 1 ps
3
4 module cross_impl #()
5 (
6         input  wire [3:0] can_rx,
7         output wire [3:0] can_tx,
8         input  wire [3:0] ifc_tx,
9         output wire [3:0] ifc_rx,
10         output wire can_stby,
11         
12         input wire  [31:0] ctrl_word
13 );
14 wire [1:0] can1_line;
15 wire [1:0] can2_line;
16 wire [1:0] can3_line;
17 wire [1:0] can4_line;
18 wire [1:0] ifc1_line;
19 wire [1:0] ifc2_line;
20 wire [1:0] ifc3_line;
21 wire [1:0] ifc4_line;
22 wire [3:0] can_en;
23
24 assign {can4_line, can3_line, can2_line, can1_line} = ctrl_word[7:0];
25 assign {ifc4_line, ifc3_line, ifc2_line, ifc1_line} = ctrl_word[15:8];
26 assign can_en = ctrl_word[20:16];
27 assign can_stby = ctrl_word[21];
28
29 wire [3:0] line_rx;
30 wire [3:0] line_tx;
31
32 /*
33 assign ifc_rx[0] = (ifc1_line == 0 ? line_rx[0] : 1'b1)
34                  & (ifc1_line == 1 ? line_rx[1] : 1'b1)
35                  & (ifc1_line == 2 ? line_rx[2] : 1'b1)
36                  & (ifc1_line == 3 ? line_rx[3] : 1'b1);
37 assign ifc_rx[1] = (ifc2_line == 0 ? line_rx[0] : 1'b1)
38                  & (ifc2_line == 1 ? line_rx[1] : 1'b1)
39                  & (ifc2_line == 2 ? line_rx[2] : 1'b1)
40                  & (ifc2_line == 3 ? line_rx[3] : 1'b1);
41 assign ifc_rx[2] = (ifc3_line == 0 ? line_rx[0] : 1'b1)
42                  & (ifc3_line == 1 ? line_rx[1] : 1'b1)
43                  & (ifc3_line == 2 ? line_rx[2] : 1'b1)
44                  & (ifc3_line == 3 ? line_rx[3] : 1'b1);
45 assign ifc_rx[3] = (ifc4_line == 0 ? line_rx[0] : 1'b1)
46                  & (ifc4_line == 1 ? line_rx[1] : 1'b1)
47                  & (ifc4_line == 2 ? line_rx[2] : 1'b1)
48                  & (ifc4_line == 3 ? line_rx[3] : 1'b1);
49 */
50 assign ifc_rx[0] = line_rx[ifc1_line];
51 assign ifc_rx[1] = line_rx[ifc2_line];
52 assign ifc_rx[2] = line_rx[ifc3_line];
53 assign ifc_rx[3] = line_rx[ifc4_line];
54
55 assign line_rx[0] = ~can_en[0] ? 1'b1 :
56                    (can1_line == 0 ? can_rx[0] : 1'b1)
57                  & (can1_line == 1 ? can_rx[1] : 1'b1)
58                  & (can1_line == 2 ? can_rx[2] : 1'b1)
59                  & (can1_line == 3 ? can_rx[3] : 1'b1);
60 assign line_rx[1] = ~can_en[1] ? 1'b1 :
61                    (can2_line == 0 ? can_rx[0] : 1'b1)
62                  & (can2_line == 1 ? can_rx[1] : 1'b1)
63                  & (can2_line == 2 ? can_rx[2] : 1'b1)
64                  & (can2_line == 3 ? can_rx[3] : 1'b1);
65 assign line_rx[2] = ~can_en[2] ? 1'b1 :
66                    (can3_line == 0 ? can_rx[0] : 1'b1)
67                  & (can3_line == 1 ? can_rx[1] : 1'b1)
68                  & (can3_line == 2 ? can_rx[2] : 1'b1)
69                  & (can3_line == 3 ? can_rx[3] : 1'b1);
70 assign line_rx[3] = ~can_en[3] ? 1'b1 :
71                    (can4_line == 0 ? can_rx[0] : 1'b1)
72                  & (can4_line == 1 ? can_rx[1] : 1'b1)
73                  & (can4_line == 2 ? can_rx[2] : 1'b1)
74                  & (can4_line == 3 ? can_rx[3] : 1'b1);
75
76 /*
77 assign can_tx[0] = ~can_en[0] ? 1'b1 :
78                    (can1_line == 0 ? line_tx[0] : 1'b1)
79                  & (can1_line == 1 ? line_tx[1] : 1'b1)
80                  & (can1_line == 2 ? line_tx[2] : 1'b1)
81                  & (can1_line == 3 ? line_tx[3] : 1'b1);
82 assign can_tx[1] = ~can_en[1] ? 1'b1 :
83                    (can2_line == 0 ? line_tx[0] : 1'b1)
84                  & (can2_line == 1 ? line_tx[1] : 1'b1)
85                  & (can2_line == 2 ? line_tx[2] : 1'b1)
86                  & (can2_line == 3 ? line_tx[3] : 1'b1);
87 assign can_tx[2] = ~can_en[2] ? 1'b1 :
88                    (can3_line == 0 ? line_tx[0] : 1'b1)
89                  & (can3_line == 1 ? line_tx[1] : 1'b1)
90                  & (can3_line == 2 ? line_tx[2] : 1'b1)
91                  & (can3_line == 3 ? line_tx[3] : 1'b1);
92 assign can_tx[3] = ~can_en[3] ? 1'b1 :
93                    (can4_line == 0 ? line_tx[0] : 1'b1)
94                  & (can4_line == 1 ? line_tx[1] : 1'b1)
95                  & (can4_line == 2 ? line_tx[2] : 1'b1)
96                  & (can4_line == 3 ? line_tx[3] : 1'b1);
97 */
98 assign can_tx[0] = can_en[0] ? line_tx[can1_line] : 1'b1;
99 assign can_tx[1] = can_en[1] ? line_tx[can2_line] : 1'b1;
100 assign can_tx[2] = can_en[2] ? line_tx[can3_line] : 1'b1;
101 assign can_tx[3] = can_en[3] ? line_tx[can4_line] : 1'b1;
102
103 assign line_tx[0] = (ifc1_line == 0 ? ifc_tx[0] : 1'b1)
104                   & (ifc1_line == 1 ? ifc_tx[1] : 1'b1)
105                   & (ifc1_line == 2 ? ifc_tx[2] : 1'b1)
106                   & (ifc1_line == 3 ? ifc_tx[3] : 1'b1);
107 assign line_tx[1] = (ifc2_line == 0 ? ifc_tx[0] : 1'b1)
108                   & (ifc2_line == 1 ? ifc_tx[1] : 1'b1)
109                   & (ifc2_line == 2 ? ifc_tx[2] : 1'b1)
110                   & (ifc2_line == 3 ? ifc_tx[3] : 1'b1);
111 assign line_tx[2] = (ifc3_line == 0 ? ifc_tx[0] : 1'b1)
112                   & (ifc3_line == 1 ? ifc_tx[1] : 1'b1)
113                   & (ifc3_line == 2 ? ifc_tx[2] : 1'b1)
114                   & (ifc3_line == 3 ? ifc_tx[3] : 1'b1);
115 assign line_tx[3] = (ifc4_line == 0 ? ifc_tx[0] : 1'b1)
116                   & (ifc4_line == 1 ? ifc_tx[1] : 1'b1)
117                   & (ifc4_line == 2 ? ifc_tx[2] : 1'b1)
118                   & (ifc4_line == 3 ? ifc_tx[3] : 1'b1);
119
120 endmodule
121
122         module can_crossbar_v1_0_S00_AXI #
123         (
124                 // Users to add parameters here
125
126                 // User parameters ends
127                 // Do not modify the parameters beyond this line
128
129                 // Width of S_AXI data bus
130                 parameter integer C_S_AXI_DATA_WIDTH    = 32,
131                 // Width of S_AXI address bus
132                 parameter integer C_S_AXI_ADDR_WIDTH    = 4
133         )
134         (
135                 // Users to add ports here
136                 input  wire [3:0] can_rx,
137                 output wire [3:0] can_tx,
138                 input  wire [3:0] ifc_tx,
139                 output wire [3:0] ifc_rx,
140                 output wire can_stby,
141                 // User ports ends
142                 // Do not modify the ports beyond this line
143
144                 // Global Clock Signal
145                 input wire  S_AXI_ACLK,
146                 // Global Reset Signal. This Signal is Active LOW
147                 input wire  S_AXI_ARESETN,
148                 // Write address (issued by master, acceped by Slave)
149                 input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_AWADDR,
150                 // Write channel Protection type. This signal indicates the
151                 // privilege and security level of the transaction, and whether
152                 // the transaction is a data access or an instruction access.
153                 input wire [2 : 0] S_AXI_AWPROT,
154                 // Write address valid. This signal indicates that the master signaling
155                 // valid write address and control information.
156                 input wire  S_AXI_AWVALID,
157                 // Write address ready. This signal indicates that the slave is ready
158                 // to accept an address and associated control signals.
159                 output wire  S_AXI_AWREADY,
160                 // Write data (issued by master, acceped by Slave) 
161                 input wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_WDATA,
162                 // Write strobes. This signal indicates which byte lanes hold
163                 // valid data. There is one write strobe bit for each eight
164                 // bits of the write data bus.    
165                 input wire [(C_S_AXI_DATA_WIDTH/8)-1 : 0] S_AXI_WSTRB,
166                 // Write valid. This signal indicates that valid write
167                 // data and strobes are available.
168                 input wire  S_AXI_WVALID,
169                 // Write ready. This signal indicates that the slave
170                 // can accept the write data.
171                 output wire  S_AXI_WREADY,
172                 // Write response. This signal indicates the status
173                 // of the write transaction.
174                 output wire [1 : 0] S_AXI_BRESP,
175                 // Write response valid. This signal indicates that the channel
176                 // is signaling a valid write response.
177                 output wire  S_AXI_BVALID,
178                 // Response ready. This signal indicates that the master
179                 // can accept a write response.
180                 input wire  S_AXI_BREADY,
181                 // Read address (issued by master, acceped by Slave)
182                 input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_ARADDR,
183                 // Protection type. This signal indicates the privilege
184                 // and security level of the transaction, and whether the
185                 // transaction is a data access or an instruction access.
186                 input wire [2 : 0] S_AXI_ARPROT,
187                 // Read address valid. This signal indicates that the channel
188                 // is signaling valid read address and control information.
189                 input wire  S_AXI_ARVALID,
190                 // Read address ready. This signal indicates that the slave is
191                 // ready to accept an address and associated control signals.
192                 output wire  S_AXI_ARREADY,
193                 // Read data (issued by slave)
194                 output wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_RDATA,
195                 // Read response. This signal indicates the status of the
196                 // read transfer.
197                 output wire [1 : 0] S_AXI_RRESP,
198                 // Read valid. This signal indicates that the channel is
199                 // signaling the required read data.
200                 output wire  S_AXI_RVALID,
201                 // Read ready. This signal indicates that the master can
202                 // accept the read data and response information.
203                 input wire  S_AXI_RREADY
204         );
205
206         // AXI4LITE signals
207         reg [C_S_AXI_ADDR_WIDTH-1 : 0]  axi_awaddr;
208         reg     axi_awready;
209         reg     axi_wready;
210         reg [1 : 0]     axi_bresp;
211         reg     axi_bvalid;
212         reg [C_S_AXI_ADDR_WIDTH-1 : 0]  axi_araddr;
213         reg     axi_arready;
214         reg [C_S_AXI_DATA_WIDTH-1 : 0]  axi_rdata;
215         reg [1 : 0]     axi_rresp;
216         reg     axi_rvalid;
217
218         // Example-specific design signals
219         // local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH
220         // ADDR_LSB is used for addressing 32/64 bit registers/memories
221         // ADDR_LSB = 2 for 32 bits (n downto 2)
222         // ADDR_LSB = 3 for 64 bits (n downto 3)
223         localparam integer ADDR_LSB = (C_S_AXI_DATA_WIDTH/32) + 1;
224         localparam integer OPT_MEM_ADDR_BITS = 1;
225         //----------------------------------------------
226         //-- Signals for user logic register space example
227         //------------------------------------------------
228         //-- Number of Slave Registers 4
229         reg [C_S_AXI_DATA_WIDTH-1:0]    slv_reg0;
230         reg [C_S_AXI_DATA_WIDTH-1:0]    slv_reg1;
231         reg [C_S_AXI_DATA_WIDTH-1:0]    slv_reg2;
232         reg [C_S_AXI_DATA_WIDTH-1:0]    slv_reg3;
233         wire     slv_reg_rden;
234         wire     slv_reg_wren;
235         reg [C_S_AXI_DATA_WIDTH-1:0]     reg_data_out;
236         integer  byte_index;
237
238         // I/O Connections assignments
239
240         assign S_AXI_AWREADY    = axi_awready;
241         assign S_AXI_WREADY     = axi_wready;
242         assign S_AXI_BRESP      = axi_bresp;
243         assign S_AXI_BVALID     = axi_bvalid;
244         assign S_AXI_ARREADY    = axi_arready;
245         assign S_AXI_RDATA      = axi_rdata;
246         assign S_AXI_RRESP      = axi_rresp;
247         assign S_AXI_RVALID     = axi_rvalid;
248         // Implement axi_awready generation
249         // axi_awready is asserted for one S_AXI_ACLK clock cycle when both
250         // S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is
251         // de-asserted when reset is low.
252
253         always @( posedge S_AXI_ACLK )
254         begin
255           if ( S_AXI_ARESETN == 1'b0 )
256             begin
257               axi_awready <= 1'b0;
258             end 
259           else
260             begin    
261               if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID)
262                 begin
263                   // slave is ready to accept write address when 
264                   // there is a valid write address and write data
265                   // on the write address and data bus. This design 
266                   // expects no outstanding transactions. 
267                   axi_awready <= 1'b1;
268                 end
269               else           
270                 begin
271                   axi_awready <= 1'b0;
272                 end
273             end 
274         end       
275
276         // Implement axi_awaddr latching
277         // This process is used to latch the address when both 
278         // S_AXI_AWVALID and S_AXI_WVALID are valid. 
279
280         always @( posedge S_AXI_ACLK )
281         begin
282           if ( S_AXI_ARESETN == 1'b0 )
283             begin
284               axi_awaddr <= 0;
285             end 
286           else
287             begin    
288               if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID)
289                 begin
290                   // Write Address latching 
291                   axi_awaddr <= S_AXI_AWADDR;
292                 end
293             end 
294         end       
295
296         // Implement axi_wready generation
297         // axi_wready is asserted for one S_AXI_ACLK clock cycle when both
298         // S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is 
299         // de-asserted when reset is low. 
300
301         always @( posedge S_AXI_ACLK )
302         begin
303           if ( S_AXI_ARESETN == 1'b0 )
304             begin
305               axi_wready <= 1'b0;
306             end 
307           else
308             begin    
309               if (~axi_wready && S_AXI_WVALID && S_AXI_AWVALID)
310                 begin
311                   // slave is ready to accept write data when 
312                   // there is a valid write address and write data
313                   // on the write address and data bus. This design 
314                   // expects no outstanding transactions. 
315                   axi_wready <= 1'b1;
316                 end
317               else
318                 begin
319                   axi_wready <= 1'b0;
320                 end
321             end 
322         end       
323
324         // Implement memory mapped register select and write logic generation
325         // The write data is accepted and written to memory mapped registers when
326         // axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to
327         // select byte enables of slave registers while writing.
328         // These registers are cleared when reset (active low) is applied.
329         // Slave register write enable is asserted when valid address and data are available
330         // and the slave is ready to accept the write address and write data.
331         assign slv_reg_wren = axi_wready && S_AXI_WVALID && axi_awready && S_AXI_AWVALID;
332
333         always @( posedge S_AXI_ACLK )
334         begin
335           if ( S_AXI_ARESETN == 1'b0 )
336             begin
337               slv_reg0 <= 32'b0_1111_11_10_01_00_11_10_01_00;
338               slv_reg1 <= 0;
339               slv_reg2 <= 0;
340               slv_reg3 <= 0;
341             end 
342           else begin
343             if (slv_reg_wren)
344               begin
345                 case ( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
346                   2'h0:
347                     for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
348                       if ( S_AXI_WSTRB[byte_index] == 1 ) begin
349                         // Respective byte enables are asserted as per write strobes 
350                         // Slave register 0
351                         slv_reg0[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
352                       end  
353                   2'h1:
354                     for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
355                       if ( S_AXI_WSTRB[byte_index] == 1 ) begin
356                         // Respective byte enables are asserted as per write strobes 
357                         // Slave register 1
358                         slv_reg1[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
359                       end  
360                   2'h2:
361                     for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
362                       if ( S_AXI_WSTRB[byte_index] == 1 ) begin
363                         // Respective byte enables are asserted as per write strobes 
364                         // Slave register 2
365                         slv_reg2[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
366                       end  
367                   2'h3:
368                     for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
369                       if ( S_AXI_WSTRB[byte_index] == 1 ) begin
370                         // Respective byte enables are asserted as per write strobes 
371                         // Slave register 3
372                         slv_reg3[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
373                       end  
374                   default : begin
375                               slv_reg0 <= slv_reg0;
376                               slv_reg1 <= slv_reg1;
377                               slv_reg2 <= slv_reg2;
378                               slv_reg3 <= slv_reg3;
379                             end
380                 endcase
381               end
382           end
383         end    
384
385         // Implement write response logic generation
386         // The write response and response valid signals are asserted by the slave 
387         // when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted.  
388         // This marks the acceptance of address and indicates the status of 
389         // write transaction.
390
391         always @( posedge S_AXI_ACLK )
392         begin
393           if ( S_AXI_ARESETN == 1'b0 )
394             begin
395               axi_bvalid  <= 0;
396               axi_bresp   <= 2'b0;
397             end 
398           else
399             begin    
400               if (axi_awready && S_AXI_AWVALID && ~axi_bvalid && axi_wready && S_AXI_WVALID)
401                 begin
402                   // indicates a valid write response is available
403                   axi_bvalid <= 1'b1;
404                   axi_bresp  <= 2'b0; // 'OKAY' response 
405                 end                   // work error responses in future
406               else
407                 begin
408                   if (S_AXI_BREADY && axi_bvalid) 
409                     //check if bready is asserted while bvalid is high) 
410                     //(there is a possibility that bready is always asserted high)   
411                     begin
412                       axi_bvalid <= 1'b0; 
413                     end  
414                 end
415             end
416         end   
417
418         // Implement axi_arready generation
419         // axi_arready is asserted for one S_AXI_ACLK clock cycle when
420         // S_AXI_ARVALID is asserted. axi_awready is 
421         // de-asserted when reset (active low) is asserted. 
422         // The read address is also latched when S_AXI_ARVALID is 
423         // asserted. axi_araddr is reset to zero on reset assertion.
424
425         always @( posedge S_AXI_ACLK )
426         begin
427           if ( S_AXI_ARESETN == 1'b0 )
428             begin
429               axi_arready <= 1'b0;
430               axi_araddr  <= 32'b0;
431             end 
432           else
433             begin    
434               if (~axi_arready && S_AXI_ARVALID)
435                 begin
436                   // indicates that the slave has acceped the valid read address
437                   axi_arready <= 1'b1;
438                   // Read address latching
439                   axi_araddr  <= S_AXI_ARADDR;
440                 end
441               else
442                 begin
443                   axi_arready <= 1'b0;
444                 end
445             end 
446         end       
447
448         // Implement axi_arvalid generation
449         // axi_rvalid is asserted for one S_AXI_ACLK clock cycle when both 
450         // S_AXI_ARVALID and axi_arready are asserted. The slave registers 
451         // data are available on the axi_rdata bus at this instance. The 
452         // assertion of axi_rvalid marks the validity of read data on the 
453         // bus and axi_rresp indicates the status of read transaction.axi_rvalid 
454         // is deasserted on reset (active low). axi_rresp and axi_rdata are 
455         // cleared to zero on reset (active low).  
456         always @( posedge S_AXI_ACLK )
457         begin
458           if ( S_AXI_ARESETN == 1'b0 )
459             begin
460               axi_rvalid <= 0;
461               axi_rresp  <= 0;
462             end 
463           else
464             begin    
465               if (axi_arready && S_AXI_ARVALID && ~axi_rvalid)
466                 begin
467                   // Valid read data is available at the read data bus
468                   axi_rvalid <= 1'b1;
469                   axi_rresp  <= 2'b0; // 'OKAY' response
470                 end   
471               else if (axi_rvalid && S_AXI_RREADY)
472                 begin
473                   // Read data is accepted by the master
474                   axi_rvalid <= 1'b0;
475                 end                
476             end
477         end    
478
479         // Implement memory mapped register select and read logic generation
480         // Slave register read enable is asserted when valid address is available
481         // and the slave is ready to accept the read address.
482         assign slv_reg_rden = axi_arready & S_AXI_ARVALID & ~axi_rvalid;
483         always @(*)
484         begin
485               // Address decoding for reading registers
486               case ( axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
487                 2'h0   : reg_data_out <= slv_reg0;
488                 2'h1   : reg_data_out <= slv_reg1;
489                 2'h2   : reg_data_out <= slv_reg2;
490                 2'h3   : reg_data_out <= slv_reg3;
491                 default : reg_data_out <= 0;
492               endcase
493         end
494
495         // Output register or memory read data
496         always @( posedge S_AXI_ACLK )
497         begin
498           if ( S_AXI_ARESETN == 1'b0 )
499             begin
500               axi_rdata  <= 0;
501             end 
502           else
503             begin    
504               // When there is a valid read address (S_AXI_ARVALID) with 
505               // acceptance of read address by the slave (axi_arready), 
506               // output the read dada 
507               if (slv_reg_rden)
508                 begin
509                   axi_rdata <= reg_data_out;     // register read data
510                 end   
511             end
512         end    
513
514         // Add user logic here
515         cross_impl #() cross_inst
516         (
517                 .can_rx(can_rx),
518                 .can_tx(can_tx),
519                 .ifc_rx(ifc_rx),
520                 .ifc_tx(ifc_tx),
521                 .can_stby(can_stby),
522                 .ctrl_word(slv_reg0)
523         );
524         // User logic ends
525
526         endmodule