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