]> rtime.felk.cvut.cz Git - fpga/zynq/canbench-sw.git/commitdiff
sja1000: synchronous with AXI, duplex register access (WIP)
authorMartin Jerabek <jerabma7@fel.cvut.cz>
Thu, 12 May 2016 11:49:54 +0000 (13:49 +0200)
committerMartin Jerabek <jerabma7@fel.cvut.cz>
Thu, 12 May 2016 23:56:00 +0000 (01:56 +0200)
system/ip/sja1000_1.0/component.xml
system/ip/sja1000_1.0/hdl/can_bsp.v
system/ip/sja1000_1.0/hdl/can_defines.v
system/ip/sja1000_1.0/hdl/can_fifo.v
system/ip/sja1000_1.0/hdl/can_ifc_axi.v
system/ip/sja1000_1.0/hdl/can_ifc_axi_sync.v [new file with mode: 0644]
system/ip/sja1000_1.0/hdl/can_ifc_axi_sync_duplex.v [new file with mode: 0644]
system/ip/sja1000_1.0/hdl/can_registers.v
system/ip/sja1000_1.0/hdl/can_top_raw.v
system/ip/sja1000_1.0/hdl/rw_arbiter.v [new file with mode: 0644]
system/ip/sja1000_1.0/hdl/sja1000.v

index f2c06f4dff879101eca5805f39cfb43e9998559a..d9ea2a291923a19bf141029f742cf466235b6ea0 100644 (file)
         <spirit:parameters>
           <spirit:parameter>
             <spirit:name>viewChecksum</spirit:name>
-            <spirit:value>4030548c</spirit:value>
+            <spirit:value>586400b8</spirit:value>
           </spirit:parameter>
         </spirit:parameters>
       </spirit:view>
         <spirit:parameters>
           <spirit:parameter>
             <spirit:name>viewChecksum</spirit:name>
-            <spirit:value>4030548c</spirit:value>
+            <spirit:value>586400b8</spirit:value>
           </spirit:parameter>
         </spirit:parameters>
       </spirit:view>
         <spirit:fileType>verilogSource</spirit:fileType>
         <spirit:logicalName>xil_defaultlib</spirit:logicalName>
       </spirit:file>
-      <spirit:file>
-        <spirit:name>hdl/can_register_syn.v</spirit:name>
-        <spirit:fileType>verilogSource</spirit:fileType>
-        <spirit:logicalName>xil_defaultlib</spirit:logicalName>
-      </spirit:file>
       <spirit:file>
         <spirit:name>hdl/can_defines.v</spirit:name>
         <spirit:fileType>verilogSource</spirit:fileType>
         <spirit:logicalName>xil_defaultlib</spirit:logicalName>
       </spirit:file>
       <spirit:file>
-        <spirit:name>hdl/can_top_raw.v</spirit:name>
+        <spirit:name>hdl/can_ifc_axi_sync_duplex.v</spirit:name>
         <spirit:fileType>verilogSource</spirit:fileType>
         <spirit:logicalName>xil_defaultlib</spirit:logicalName>
       </spirit:file>
       <spirit:file>
-        <spirit:name>hdl/can_ibo.v</spirit:name>
+        <spirit:name>hdl/can_top_raw.v</spirit:name>
         <spirit:fileType>verilogSource</spirit:fileType>
         <spirit:logicalName>xil_defaultlib</spirit:logicalName>
       </spirit:file>
       <spirit:file>
-        <spirit:name>hdl/can_acf.v</spirit:name>
+        <spirit:name>hdl/can_ibo.v</spirit:name>
         <spirit:fileType>verilogSource</spirit:fileType>
         <spirit:logicalName>xil_defaultlib</spirit:logicalName>
       </spirit:file>
       <spirit:file>
-        <spirit:name>hdl/can_ifc_axi.v</spirit:name>
+        <spirit:name>hdl/can_acf.v</spirit:name>
         <spirit:fileType>verilogSource</spirit:fileType>
         <spirit:logicalName>xil_defaultlib</spirit:logicalName>
       </spirit:file>
         <spirit:userFileType>USED_IN_ipstatic</spirit:userFileType>
         <spirit:logicalName>xil_defaultlib</spirit:logicalName>
       </spirit:file>
-      <spirit:file>
-        <spirit:name>hdl/can_register_syn.v</spirit:name>
-        <spirit:fileType>verilogSource</spirit:fileType>
-        <spirit:userFileType>USED_IN_ipstatic</spirit:userFileType>
-        <spirit:logicalName>xil_defaultlib</spirit:logicalName>
-      </spirit:file>
       <spirit:file>
         <spirit:name>hdl/can_defines.v</spirit:name>
         <spirit:fileType>verilogSource</spirit:fileType>
         <spirit:logicalName>xil_defaultlib</spirit:logicalName>
       </spirit:file>
       <spirit:file>
-        <spirit:name>hdl/can_top_raw.v</spirit:name>
+        <spirit:name>hdl/can_ifc_axi_sync_duplex.v</spirit:name>
         <spirit:fileType>verilogSource</spirit:fileType>
-        <spirit:userFileType>USED_IN_ipstatic</spirit:userFileType>
         <spirit:logicalName>xil_defaultlib</spirit:logicalName>
       </spirit:file>
       <spirit:file>
-        <spirit:name>hdl/can_ibo.v</spirit:name>
+        <spirit:name>hdl/can_top_raw.v</spirit:name>
         <spirit:fileType>verilogSource</spirit:fileType>
         <spirit:userFileType>USED_IN_ipstatic</spirit:userFileType>
         <spirit:logicalName>xil_defaultlib</spirit:logicalName>
       </spirit:file>
       <spirit:file>
-        <spirit:name>hdl/can_acf.v</spirit:name>
+        <spirit:name>hdl/can_ibo.v</spirit:name>
         <spirit:fileType>verilogSource</spirit:fileType>
         <spirit:userFileType>USED_IN_ipstatic</spirit:userFileType>
         <spirit:logicalName>xil_defaultlib</spirit:logicalName>
       </spirit:file>
       <spirit:file>
-        <spirit:name>hdl/can_ifc_axi.v</spirit:name>
+        <spirit:name>hdl/can_acf.v</spirit:name>
         <spirit:fileType>verilogSource</spirit:fileType>
         <spirit:userFileType>USED_IN_ipstatic</spirit:userFileType>
         <spirit:logicalName>xil_defaultlib</spirit:logicalName>
         <xilinx:taxonomy>AXI_Peripheral</xilinx:taxonomy>
       </xilinx:taxonomies>
       <xilinx:displayName>sja1000_v1.0</xilinx:displayName>
-      <xilinx:coreRevision>3</xilinx:coreRevision>
-      <xilinx:coreCreationDateTime>2016-05-11T10:03:38Z</xilinx:coreCreationDateTime>
+      <xilinx:coreRevision>8</xilinx:coreRevision>
+      <xilinx:coreCreationDateTime>2016-05-11T17:43:43Z</xilinx:coreCreationDateTime>
       <xilinx:tags>
         <xilinx:tag xilinx:name="user.org:user:sja1000:1.0_ARCHIVE_LOCATION">/home/martin/projects/cvut/bakalarka/canbench-sw/system/ip/sja1000_1.0</xilinx:tag>
       </xilinx:tags>
     </xilinx:coreExtensions>
     <xilinx:packagingInfo>
-      <xilinx:xilinxVersion>2015.4</xilinx:xilinxVersion>
-      <xilinx:checksum xilinx:scope="busInterfaces" xilinx:value="5dbb9758"/>
+      <xilinx:xilinxVersion>2016.1</xilinx:xilinxVersion>
+      <xilinx:checksum xilinx:scope="busInterfaces" xilinx:value="fa0dead8"/>
       <xilinx:checksum xilinx:scope="memoryMaps" xilinx:value="ca22a6c3"/>
-      <xilinx:checksum xilinx:scope="fileGroups" xilinx:value="0b6c5764"/>
+      <xilinx:checksum xilinx:scope="fileGroups" xilinx:value="25cd449f"/>
       <xilinx:checksum xilinx:scope="ports" xilinx:value="2af143f4"/>
       <xilinx:checksum xilinx:scope="hdlParameters" xilinx:value="8a3bfb41"/>
       <xilinx:checksum xilinx:scope="parameters" xilinx:value="edbec00a"/>
index 79a165ae8778c03fb52426e09d5f978d87c16910..e8205eb9dcd4a5c28d411d424894f1fa4d637a2b 100644 (file)
@@ -244,10 +244,10 @@ module can_bsp
   tx_point,
   hard_sync,
 
-  addr,
-  data_in,
-  data_out,
-  fifo_selected,
+  addr, // FIFO read address only
+  data_in, // input data for FIFO and error count settings (looks magical :/)
+  data_out, // from FIFO only
+  fifo_selected, // only forwarded
   
 
 
index f1357819bb5b269954ebb3754bc69c3d28d89215..224f593b39e6ff73dbd9cc1bf118810f5dbedca1 100644 (file)
@@ -97,7 +97,7 @@
 
 // Uncomment following line if you want to use WISHBONE interface. Otherwise
 // 8051 interface is used.
-`define   CAN_WISHBONE_IF
+//`define   CAN_WISHBONE_IF
 
 // Uncomment following line if you want to use CAN in Actel APA devices (embedded memory used)
 // `define   ACTEL_APA_RAM
index be0648f6f40b4945047aea91440b1d6a799982be..fa77a097a5be9e704c52a95202b36ac6e735cbb6 100644 (file)
@@ -154,7 +154,7 @@ module can_fifo
   wr,
 
   data_in,
-  addr,
+  addr, // read address
   data_out,
   fifo_selected,
 
index e4395360454c654283da9751d6db44083b58762c..30d8465a4cb4d28a06a79446eb13c7543bd2d066 100644 (file)
@@ -86,109 +86,6 @@ module can_ifc_async
   end
 endmodule
 
-module rw_arbiter #()
-(
-       input wire  S_AXI_ACLK,
-       input wire  S_AXI_ARESETN,
-       output reg read_pending,
-       output reg read_active,
-       output reg write_pending,
-       output reg write_active,
-       output reg read_active_edge,
-       output reg write_active_edge,
-
-       input wire read_finished,
-       input wire write_finished,
-       
-       input wire ready_read_i,
-       input wire ready_write_i
-);
-
-       wire ready_read_edge;
-       wire ready_write_edge;
-       reg  [1:0] ready_read_hist;
-       reg  [1:0] ready_write_hist;
-       assign ready_read_edge = ready_read_hist[0] ^ ready_read_hist[1];
-       assign ready_write_edge = ready_write_hist[0] ^ ready_write_hist[1];
-
-
-    // read/write arbitration
-    always @ (posedge S_AXI_ACLK or negedge S_AXI_ARESETN)
-    begin
-      if (~S_AXI_ARESETN)
-      begin
-        write_pending <= 1'b0;
-        write_active <= 1'b0;
-        read_pending <= 1'b0;
-        read_active <= 1'b0;
-        ready_read_hist <= 2'b00;
-        ready_write_hist <= 2'b00;
-      end
-      else
-      begin
-        ready_read_hist <= {ready_read_hist[0], ready_read_i};
-        ready_write_hist <= {ready_write_hist[0], ready_write_i /*& (S_AXI_WSTRB == 4'b1111)*/};
-
-        /*
-        if(S_AXI_AWVALID & S_AXI_WVALID & (S_AXI_WSTRB != 4'b1111))
-        begin
-          S_AXI_BVALID <= 1;
-          S_AXI_BRESP <= ...;
-        end
-        */
-
-        if (write_active_edge)
-          write_active_edge = 0;
-        if (read_active_edge)
-          read_active_edge = 0;
-
-        if (ready_write_edge)
-        begin
-          if (read_active & ~read_finished)
-            write_pending <= 1;
-          else
-          begin
-            write_active <= 1;
-            write_active_edge = 1;
-          end
-        end
-
-        if (ready_read_edge)
-        begin
-          if (write_active & ~write_finished)
-            read_pending <= 1;
-          else
-          begin
-            read_active <= 1;
-            read_active_edge = 1;
-          end
-        end
-
-        // read finished in previous cycle
-        if (read_finished)
-        begin
-          read_active <= 1'b0;
-          if (write_pending)
-          begin
-            write_active <= 1;
-            write_pending <= 0;
-          end
-        end
-
-        // write finished in previous cycle
-        if (write_finished)
-        begin
-          write_active <= 1'b0;
-          if (read_pending)
-          begin
-            read_active <= 1;
-            read_pending <= 0;
-          end
-        end
-      end
-    end
-endmodule
-
 module can_ifc_axi
 #(
   // Width of S_AXI data bus
diff --git a/system/ip/sja1000_1.0/hdl/can_ifc_axi_sync.v b/system/ip/sja1000_1.0/hdl/can_ifc_axi_sync.v
new file mode 100644 (file)
index 0000000..ce6f32b
--- /dev/null
@@ -0,0 +1,178 @@
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+////  can_top.v                                                   ////
+////                                                              ////
+////                                                              ////
+////  This file is part of the CAN Protocol Controller            ////
+////  http://www.opencores.org/projects/can/                      ////
+////                                                              ////
+////                                                              ////
+////  Author(s):                                                  ////
+////       Igor Mohor                                             ////
+////       igorm@opencores.org                                    ////
+////                                                              ////
+////                                                              ////
+////  All additional information is available in the README.txt   ////
+////  file.                                                       ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+//// Copyright (C) 2002, 2003, 2004 Authors                       ////
+////                                                              ////
+//// This source file may be used and distributed without         ////
+//// restriction provided that this copyright statement is not    ////
+//// removed from the file and that any derivative work contains  ////
+//// the original copyright notice and the associated disclaimer. ////
+////                                                              ////
+//// This source file is free software; you can redistribute it   ////
+//// and/or modify it under the terms of the GNU Lesser General   ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any   ////
+//// later version.                                               ////
+////                                                              ////
+//// This source is distributed in the hope that it will be       ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
+//// PURPOSE.  See the GNU Lesser General Public License for more ////
+//// details.                                                     ////
+////                                                              ////
+//// You should have received a copy of the GNU Lesser General    ////
+//// Public License along with this source; if not, download it   ////
+//// from http://www.opencores.org/lgpl.shtml                     ////
+////                                                              ////
+//// The CAN protocol is developed by Robert Bosch GmbH and       ////
+//// protected by patents. Anybody who wants to implement this    ////
+//// CAN IP core on silicon has to obtain a CAN protocol license  ////
+//// from Bosch.                                                  ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+
+// synopsys translate_off
+`include "timescale.v"
+// synopsys translate_on
+`include "can_defines.v"
+
+module can_ifc_axi_sync
+#(
+  // Width of S_AXI data bus
+  parameter integer C_S_AXI_DATA_WIDTH = 32,
+  // Width of S_AXI address bus
+  parameter integer C_S_AXI_ADDR_WIDTH = 8
+)
+(
+  output wire reg_rst_o,
+  output wire reg_cs_o,
+  output wire reg_we_o,
+  output wire [7:0] reg_addr_o,
+  output wire [7:0] reg_data_in_o,
+  input wire  [7:0] reg_data_out_i,
+
+  input wire  S_AXI_ACLK,
+  input wire  S_AXI_ARESETN,
+
+  input wire  [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_AWADDR,
+  input wire  [2:0]                      S_AXI_AWPROT,
+  input wire                             S_AXI_AWVALID,
+  output reg                             S_AXI_AWREADY,
+
+  input wire [C_S_AXI_DATA_WIDTH-1 : 0]     S_AXI_WDATA,
+  input wire [(C_S_AXI_DATA_WIDTH/8)-1 : 0] S_AXI_WSTRB,
+  input wire                                S_AXI_WVALID,
+  output reg                                S_AXI_WREADY,
+
+  output reg [1:0]                       S_AXI_BRESP,
+  output reg                             S_AXI_BVALID,
+  input wire                             S_AXI_BREADY,
+
+  input wire  [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_ARADDR,
+  input wire  [2:0]                      S_AXI_ARPROT,
+  input wire                             S_AXI_ARVALID,
+  output reg                             S_AXI_ARREADY,
+
+  output wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_RDATA,
+  output reg  [1:0]                      S_AXI_RRESP,
+  output reg                             S_AXI_RVALID,
+  input wire                             S_AXI_RREADY
+);
+
+  reg req;
+  reg oack;
+  wire ack_i;
+  wire read_active;
+  wire write_active;
+  rw_arbiter rw_arbiter_inst
+  (
+    .S_AXI_ACLK(S_AXI_ACLK),
+    .S_AXI_ARESETN(S_AXI_ARESETN),
+    .read_pending(),
+    .read_active(read_active),
+    .write_pending(),
+    .write_active(write_active),
+    .read_active_edge(read_active_edge),
+    .write_active_edge(write_active_edge),
+
+    .read_finished(S_AXI_RVALID && S_AXI_RREADY),
+    .write_finished(S_AXI_BVALID && S_AXI_BREADY),
+
+    .ready_read_i(S_AXI_ARVALID),
+    .ready_write_i(S_AXI_AWVALID & S_AXI_WVALID)
+  );
+
+
+  //assign reg_addr_o <= write ? axi_waddr : axi_raddr;
+  // assign reg_addr_o - asynchronous, synchronized by protocols expectations
+  // should not synthesise any regs or latches
+  assign reg_addr_o = write_active ? S_AXI_AWADDR :
+                      read_active  ? S_AXI_ARADDR :
+                      8'bxxxxxxxx;
+
+  always @(negedge S_AXI_ARESETN or posedge S_AXI_ACLK)
+  begin
+    if (~S_AXI_ARESETN)
+      begin
+        S_AXI_BRESP <= 2'b00; // OKAY
+        S_AXI_BVALID <= 1'b0;
+        S_AXI_WREADY <= 1'b0;
+        S_AXI_AWREADY <= 1'b0;
+        S_AXI_RRESP <= 0;
+      end else
+      begin
+        if (read_active)
+        begin
+          if (S_AXI_RREADY && S_AXI_RVALID)
+          begin
+            S_AXI_RVALID <= 1'b0;
+            S_AXI_ARREADY <= 1'b0;
+          end
+          else if (~S_AXI_RVALID)
+          begin
+            S_AXI_RVALID <= 1'b1;
+            S_AXI_ARREADY <= 1'b1;
+            S_AXI_RRESP <= 2'b00; // OKAY
+          end
+        end else if (write_active)
+        begin
+          if (S_AXI_BREADY && S_AXI_BVALID)
+          begin
+            S_AXI_BVALID <= 1'b0;
+            S_AXI_WREADY <= 1'b0;
+            S_AXI_AWREADY <= 1'b0;
+          end
+          else if (~S_AXI_BVALID)
+          begin
+            S_AXI_BRESP <= 2'b00; // OKAY
+            S_AXI_BVALID <= 1'b1;
+            S_AXI_WREADY <= 1'b1;
+            S_AXI_AWREADY <= 1'b1;
+          end
+        end
+      end
+     end
+
+  assign reg_rst_o       = ~S_AXI_ARESETN;
+  assign reg_we_o        = write_active;
+  assign reg_data_in_o   = S_AXI_WDATA[7:0];
+  assign S_AXI_RDATA[7:0]= reg_data_out_i;
+  assign S_AXI_RDATA[C_S_AXI_DATA_WIDTH-1 : 8] = 0;
+  assign reg_cs_o        = read_active | write_active;
+endmodule
diff --git a/system/ip/sja1000_1.0/hdl/can_ifc_axi_sync_duplex.v b/system/ip/sja1000_1.0/hdl/can_ifc_axi_sync_duplex.v
new file mode 100644 (file)
index 0000000..580e3cd
--- /dev/null
@@ -0,0 +1,416 @@
+// synopsys translate_off
+`include "timescale.v"
+// synopsys translate_on
+//`include "can_defines.v"
+
+       module can_ifc_axi_sync_duplex #
+       (
+               // Users to add parameters here
+
+               // User parameters ends
+               // Do not modify the parameters beyond this line
+
+               // Width of S_AXI data bus
+               parameter integer C_S_AXI_DATA_WIDTH    = 32,
+               // Width of S_AXI address bus
+               parameter integer C_S_AXI_ADDR_WIDTH    = 8
+       )
+       (
+               // Users to add ports here
+               output wire reg_rst_o,
+               output wire reg_re_o,
+               output wire reg_we_o,
+               output wire [7:0] reg_addr_read_o,
+               output wire [7:0] reg_addr_write_o,
+               output wire [7:0] reg_data_in_o,
+               input wire  [7:0] reg_data_out_i,
+
+               // User ports ends
+               // Do not modify the ports beyond this line
+
+               // Global Clock Signal
+               input wire  S_AXI_ACLK,
+               // Global Reset Signal. This Signal is Active LOW
+               input wire  S_AXI_ARESETN,
+               // Write address (issued by master, acceped by Slave)
+               input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_AWADDR,
+               // Write channel Protection type. This signal indicates the
+               // privilege and security level of the transaction, and whether
+               // the transaction is a data access or an instruction access.
+               input wire [2 : 0] S_AXI_AWPROT,
+               // Write address valid. This signal indicates that the master signaling
+               // valid write address and control information.
+               input wire  S_AXI_AWVALID,
+               // Write address ready. This signal indicates that the slave is ready
+               // to accept an address and associated control signals.
+               output wire  S_AXI_AWREADY,
+               // Write data (issued by master, acceped by Slave) 
+               input wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_WDATA,
+               // Write strobes. This signal indicates which byte lanes hold
+               // valid data. There is one write strobe bit for each eight
+               // bits of the write data bus.    
+               input wire [(C_S_AXI_DATA_WIDTH/8)-1 : 0] S_AXI_WSTRB,
+               // Write valid. This signal indicates that valid write
+               // data and strobes are available.
+               input wire  S_AXI_WVALID,
+               // Write ready. This signal indicates that the slave
+               // can accept the write data.
+               output wire  S_AXI_WREADY,
+               // Write response. This signal indicates the status
+               // of the write transaction.
+               output wire [1 : 0] S_AXI_BRESP,
+               // Write response valid. This signal indicates that the channel
+               // is signaling a valid write response.
+               output wire  S_AXI_BVALID,
+               // Response ready. This signal indicates that the master
+               // can accept a write response.
+               input wire  S_AXI_BREADY,
+               // Read address (issued by master, acceped by Slave)
+               input wire [C_S_AXI_ADDR_WIDTH-1 : 0] S_AXI_ARADDR,
+               // Protection type. This signal indicates the privilege
+               // and security level of the transaction, and whether the
+               // transaction is a data access or an instruction access.
+               input wire [2 : 0] S_AXI_ARPROT,
+               // Read address valid. This signal indicates that the channel
+               // is signaling valid read address and control information.
+               input wire  S_AXI_ARVALID,
+               // Read address ready. This signal indicates that the slave is
+               // ready to accept an address and associated control signals.
+               output wire  S_AXI_ARREADY,
+               // Read data (issued by slave)
+               output wire [C_S_AXI_DATA_WIDTH-1 : 0] S_AXI_RDATA,
+               // Read response. This signal indicates the status of the
+               // read transfer.
+               output wire [1 : 0] S_AXI_RRESP,
+               // Read valid. This signal indicates that the channel is
+               // signaling the required read data.
+               output wire  S_AXI_RVALID,
+               // Read ready. This signal indicates that the master can
+               // accept the read data and response information.
+               input wire  S_AXI_RREADY
+       );
+
+       // AXI4LITE signals
+       reg [C_S_AXI_ADDR_WIDTH-1 : 0]  axi_awaddr;
+       reg     axi_awready;
+       reg     axi_wready;
+       reg [1 : 0]     axi_bresp;
+       reg     axi_bvalid;
+       reg [C_S_AXI_ADDR_WIDTH-1 : 0]  axi_araddr;
+       reg     axi_arready;
+       reg [C_S_AXI_DATA_WIDTH-1 : 0]  axi_rdata;
+       reg [1 : 0]     axi_rresp;
+       reg     axi_rvalid;
+
+       // Example-specific design signals
+       // local parameter for addressing 32 bit / 64 bit C_S_AXI_DATA_WIDTH
+       // ADDR_LSB is used for addressing 32/64 bit registers/memories
+       // ADDR_LSB = 2 for 32 bits (n downto 2)
+       // ADDR_LSB = 3 for 64 bits (n downto 3)
+       localparam integer ADDR_LSB = (C_S_AXI_DATA_WIDTH/32) + 1;
+       localparam integer OPT_MEM_ADDR_BITS = 1;
+       //----------------------------------------------
+       //-- Signals for user logic register space example
+       //------------------------------------------------
+       //-- Number of Slave Registers 4
+       /*reg [C_S_AXI_DATA_WIDTH-1:0]  slv_reg0;
+       reg [C_S_AXI_DATA_WIDTH-1:0]    slv_reg1;
+       reg [C_S_AXI_DATA_WIDTH-1:0]    slv_reg2;
+       reg [C_S_AXI_DATA_WIDTH-1:0]    slv_reg3;*/
+       wire     slv_reg_rden;
+       wire     slv_reg_wren;
+       //reg [C_S_AXI_DATA_WIDTH-1:0]   reg_data_out;
+       //integer        byte_index;
+
+       // I/O Connections assignments
+
+       assign S_AXI_AWREADY    = axi_awready;
+       assign S_AXI_WREADY     = axi_wready;
+       assign S_AXI_BRESP      = axi_bresp;
+       assign S_AXI_BVALID     = axi_bvalid;
+       assign S_AXI_ARREADY    = axi_arready;
+       assign S_AXI_RDATA      = axi_rdata;
+       assign S_AXI_RRESP      = axi_rresp;
+       assign S_AXI_RVALID     = axi_rvalid;
+       // Implement axi_awready generation
+       // axi_awready is asserted for one S_AXI_ACLK clock cycle when both
+       // S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_awready is
+       // de-asserted when reset is low.
+
+       always @( posedge S_AXI_ACLK )
+       begin
+         if ( S_AXI_ARESETN == 1'b0 )
+           begin
+             axi_awready <= 1'b0;
+           end 
+         else
+           begin    
+             if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID)
+               begin
+                 // slave is ready to accept write address when 
+                 // there is a valid write address and write data
+                 // on the write address and data bus. This design 
+                 // expects no outstanding transactions. 
+                 axi_awready <= 1'b1;
+               end
+             else           
+               begin
+                 axi_awready <= 1'b0;
+               end
+           end 
+       end       
+
+       // Implement axi_awaddr latching
+       // This process is used to latch the address when both 
+       // S_AXI_AWVALID and S_AXI_WVALID are valid. 
+
+       always @( posedge S_AXI_ACLK )
+       begin
+         if ( S_AXI_ARESETN == 1'b0 )
+           begin
+             axi_awaddr <= 0;
+           end 
+         else
+           begin    
+             if (~axi_awready && S_AXI_AWVALID && S_AXI_WVALID)
+               begin
+                 // Write Address latching 
+                 axi_awaddr <= S_AXI_AWADDR;
+               end
+           end 
+       end       
+
+       // Implement axi_wready generation
+       // axi_wready is asserted for one S_AXI_ACLK clock cycle when both
+       // S_AXI_AWVALID and S_AXI_WVALID are asserted. axi_wready is 
+       // de-asserted when reset is low. 
+
+       always @( posedge S_AXI_ACLK )
+       begin
+         if ( S_AXI_ARESETN == 1'b0 )
+           begin
+             axi_wready <= 1'b0;
+           end 
+         else
+           begin    
+             if (~axi_wready && S_AXI_WVALID && S_AXI_AWVALID)
+               begin
+                 // slave is ready to accept write data when 
+                 // there is a valid write address and write data
+                 // on the write address and data bus. This design 
+                 // expects no outstanding transactions. 
+                 axi_wready <= 1'b1;
+               end
+             else
+               begin
+                 axi_wready <= 1'b0;
+               end
+           end 
+       end       
+
+       // Implement memory mapped register select and write logic generation
+       // The write data is accepted and written to memory mapped registers when
+       // axi_awready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted. Write strobes are used to
+       // select byte enables of slave registers while writing.
+       // These registers are cleared when reset (active low) is applied.
+       // Slave register write enable is asserted when valid address and data are available
+       // and the slave is ready to accept the write address and write data.
+       assign slv_reg_wren = axi_wready && S_AXI_WVALID && axi_awready && S_AXI_AWVALID;
+       /*
+       always @( posedge S_AXI_ACLK )
+       begin
+         if ( S_AXI_ARESETN == 1'b0 )
+           begin
+             slv_reg0 <= 0;
+             slv_reg1 <= 0;
+             slv_reg2 <= 0;
+             slv_reg3 <= 0;
+           end 
+         else begin
+           if (slv_reg_wren)
+             begin
+               case ( axi_awaddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
+                 2'h0:
+                   for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
+                     if ( S_AXI_WSTRB[byte_index] == 1 ) begin
+                       // Respective byte enables are asserted as per write strobes 
+                       // Slave register 0
+                       slv_reg0[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
+                     end  
+                 2'h1:
+                   for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
+                     if ( S_AXI_WSTRB[byte_index] == 1 ) begin
+                       // Respective byte enables are asserted as per write strobes 
+                       // Slave register 1
+                       slv_reg1[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
+                     end  
+                 2'h2:
+                   for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
+                     if ( S_AXI_WSTRB[byte_index] == 1 ) begin
+                       // Respective byte enables are asserted as per write strobes 
+                       // Slave register 2
+                       slv_reg2[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
+                     end  
+                 2'h3:
+                   for ( byte_index = 0; byte_index <= (C_S_AXI_DATA_WIDTH/8)-1; byte_index = byte_index+1 )
+                     if ( S_AXI_WSTRB[byte_index] == 1 ) begin
+                       // Respective byte enables are asserted as per write strobes 
+                       // Slave register 3
+                       slv_reg3[(byte_index*8) +: 8] <= S_AXI_WDATA[(byte_index*8) +: 8];
+                     end  
+                 default : begin
+                             slv_reg0 <= slv_reg0;
+                             slv_reg1 <= slv_reg1;
+                             slv_reg2 <= slv_reg2;
+                             slv_reg3 <= slv_reg3;
+                           end
+               endcase
+             end
+         end
+       end    
+       */
+
+       // Implement write response logic generation
+       // The write response and response valid signals are asserted by the slave 
+       // when axi_wready, S_AXI_WVALID, axi_wready and S_AXI_WVALID are asserted.  
+       // This marks the acceptance of address and indicates the status of 
+       // write transaction.
+
+       always @( posedge S_AXI_ACLK )
+       begin
+         if ( S_AXI_ARESETN == 1'b0 )
+           begin
+             axi_bvalid  <= 0;
+             axi_bresp   <= 2'b0;
+           end 
+         else
+           begin    
+             if (axi_awready && S_AXI_AWVALID && ~axi_bvalid && axi_wready && S_AXI_WVALID)
+               begin
+                 // indicates a valid write response is available
+                 axi_bvalid <= 1'b1;
+                 axi_bresp  <= 2'b0; // 'OKAY' response 
+               end                   // work error responses in future
+             else
+               begin
+                 if (S_AXI_BREADY && axi_bvalid) 
+                   //check if bready is asserted while bvalid is high) 
+                   //(there is a possibility that bready is always asserted high)   
+                   begin
+                     axi_bvalid <= 1'b0; 
+                   end  
+               end
+           end
+       end   
+
+       // Implement axi_arready generation
+       // axi_arready is asserted for one S_AXI_ACLK clock cycle when
+       // S_AXI_ARVALID is asserted. axi_awready is 
+       // de-asserted when reset (active low) is asserted. 
+       // The read address is also latched when S_AXI_ARVALID is 
+       // asserted. axi_araddr is reset to zero on reset assertion.
+
+       always @( posedge S_AXI_ACLK )
+       begin
+         if ( S_AXI_ARESETN == 1'b0 )
+           begin
+             axi_arready <= 1'b0;
+             axi_araddr  <= 32'b0;
+           end 
+         else
+           begin    
+             if (~axi_arready && S_AXI_ARVALID)
+               begin
+                 // indicates that the slave has acceped the valid read address
+                 axi_arready <= 1'b1;
+                 // Read address latching
+                 axi_araddr  <= S_AXI_ARADDR;
+               end
+             else
+               begin
+                 axi_arready <= 1'b0;
+               end
+           end 
+       end       
+
+       // Implement axi_arvalid generation
+       // axi_rvalid is asserted for one S_AXI_ACLK clock cycle when both 
+       // S_AXI_ARVALID and axi_arready are asserted. The slave registers 
+       // data are available on the axi_rdata bus at this instance. The 
+       // assertion of axi_rvalid marks the validity of read data on the 
+       // bus and axi_rresp indicates the status of read transaction.axi_rvalid 
+       // is deasserted on reset (active low). axi_rresp and axi_rdata are 
+       // cleared to zero on reset (active low).  
+       always @( posedge S_AXI_ACLK )
+       begin
+         if ( S_AXI_ARESETN == 1'b0 )
+           begin
+             axi_rvalid <= 0;
+             axi_rresp  <= 0;
+           end 
+         else
+           begin    
+             if (axi_arready && S_AXI_ARVALID && ~axi_rvalid)
+               begin
+                 // Valid read data is available at the read data bus
+                 axi_rvalid <= 1'b1;
+                 axi_rresp  <= 2'b0; // 'OKAY' response
+               end   
+             else if (axi_rvalid && S_AXI_RREADY)
+               begin
+                 // Read data is accepted by the master
+                 axi_rvalid <= 1'b0;
+               end                
+           end
+       end    
+
+       // Implement memory mapped register select and read logic generation
+       // Slave register read enable is asserted when valid address is available
+       // and the slave is ready to accept the read address.
+       assign slv_reg_rden = axi_arready & S_AXI_ARVALID & ~axi_rvalid;
+       /*
+       always @(*)
+       begin
+             // Address decoding for reading registers
+             case ( axi_araddr[ADDR_LSB+OPT_MEM_ADDR_BITS:ADDR_LSB] )
+               2'h0   : reg_data_out <= slv_reg0;
+               2'h1   : reg_data_out <= slv_reg1;
+               2'h2   : reg_data_out <= slv_reg2;
+               2'h3   : reg_data_out <= slv_reg3;
+               default : reg_data_out <= 0;
+             endcase
+       end
+       */
+
+       // Output register or memory read data
+       always @( posedge S_AXI_ACLK )
+       begin
+         if ( S_AXI_ARESETN == 1'b0 )
+           begin
+             axi_rdata  <= 0;
+           end 
+         else
+           begin    
+             // When there is a valid read address (S_AXI_ARVALID) with 
+             // acceptance of read address by the slave (axi_arready), 
+             // output the read dada 
+             if (slv_reg_rden)
+               begin
+                 axi_rdata[7:0] <= reg_data_out_i;     // register read data
+                 axi_rdata[C_S_AXI_DATA_WIDTH-1 : 8] <= 0;
+               end   
+           end
+       end    
+
+       // Add user logic here
+       assign reg_addr_read_o = S_AXI_ARADDR;
+       assign reg_addr_write_o= S_AXI_AWADDR;
+       assign reg_rst_o       = ~S_AXI_ARESETN;
+       assign reg_re_o        = slv_reg_rden;
+       assign reg_we_o        = slv_reg_wren;
+       assign reg_data_in_o   = S_AXI_WDATA[7:0];
+       //assign reg_data_out    = reg_data_out_i;
+
+       // User logic ends
+
+       endmodule
index 0fed03f2f4ef408bff7f63915e9c853bed224a9e..811f57770bbc91436c06e93b4e7e83d9876dad85 100644 (file)
@@ -174,9 +174,10 @@ module can_registers
 ( 
   clk,
   rst,
-  cs,
+  re,
   we,
-  addr,
+  addr_read,
+  addr_write,
   data_in,
   data_out,
   irq_n,
@@ -296,9 +297,10 @@ parameter Tp = 1;
 
 input         clk;
 input         rst;
-input         cs;
+input         re;
 input         we;
-input   [7:0] addr;
+input   [7:0] addr_read;
+input   [7:0] addr_write;
 input   [7:0] data_in;
 
 output  [7:0] data_out;
@@ -441,48 +443,51 @@ wire          receive_irq_en;
 wire    [7:0] irq_reg;
 wire          irq;
 
-wire we_mode                  = cs & we & (addr == 8'd0);
-wire we_command               = cs & we & (addr == 8'd1);
-wire we_bus_timing_0          = cs & we & (addr == 8'd6) & reset_mode;
-wire we_bus_timing_1          = cs & we & (addr == 8'd7) & reset_mode;
-wire we_clock_divider_low     = cs & we & (addr == 8'd31);
+wire cs;
+assign cs = 1'b1;
+
+wire we_mode                  = cs & we & (addr_write == 8'd0);
+wire we_command               = cs & we & (addr_write == 8'd1);
+wire we_bus_timing_0          = cs & we & (addr_write == 8'd6) & reset_mode;
+wire we_bus_timing_1          = cs & we & (addr_write == 8'd7) & reset_mode;
+wire we_clock_divider_low     = cs & we & (addr_write == 8'd31);
 wire we_clock_divider_hi      = we_clock_divider_low & reset_mode;
 
-wire read = cs & (~we);
-wire read_irq_reg = read & (addr == 8'd3);
-assign read_arbitration_lost_capture_reg = read & extended_mode & (addr == 8'd11);
-assign read_error_code_capture_reg = read & extended_mode & (addr == 8'd12);
+wire read = cs & re;
+wire read_irq_reg = read & (addr_read == 8'd3);
+assign read_arbitration_lost_capture_reg = read & extended_mode & (addr_read == 8'd11);
+assign read_error_code_capture_reg = read & extended_mode & (addr_read == 8'd12);
 
 /* This section is for BASIC and EXTENDED mode */
-wire we_acceptance_code_0       = cs & we &   reset_mode  & ((~extended_mode) & (addr == 8'd4)  | extended_mode & (addr == 8'd16));
-wire we_acceptance_mask_0       = cs & we &   reset_mode  & ((~extended_mode) & (addr == 8'd5)  | extended_mode & (addr == 8'd20));
-wire we_tx_data_0               = cs & we & (~reset_mode) & ((~extended_mode) & (addr == 8'd10) | extended_mode & (addr == 8'd16)) & transmit_buffer_status;
-wire we_tx_data_1               = cs & we & (~reset_mode) & ((~extended_mode) & (addr == 8'd11) | extended_mode & (addr == 8'd17)) & transmit_buffer_status;
-wire we_tx_data_2               = cs & we & (~reset_mode) & ((~extended_mode) & (addr == 8'd12) | extended_mode & (addr == 8'd18)) & transmit_buffer_status;
-wire we_tx_data_3               = cs & we & (~reset_mode) & ((~extended_mode) & (addr == 8'd13) | extended_mode & (addr == 8'd19)) & transmit_buffer_status;
-wire we_tx_data_4               = cs & we & (~reset_mode) & ((~extended_mode) & (addr == 8'd14) | extended_mode & (addr == 8'd20)) & transmit_buffer_status;
-wire we_tx_data_5               = cs & we & (~reset_mode) & ((~extended_mode) & (addr == 8'd15) | extended_mode & (addr == 8'd21)) & transmit_buffer_status;
-wire we_tx_data_6               = cs & we & (~reset_mode) & ((~extended_mode) & (addr == 8'd16) | extended_mode & (addr == 8'd22)) & transmit_buffer_status;
-wire we_tx_data_7               = cs & we & (~reset_mode) & ((~extended_mode) & (addr == 8'd17) | extended_mode & (addr == 8'd23)) & transmit_buffer_status;
-wire we_tx_data_8               = cs & we & (~reset_mode) & ((~extended_mode) & (addr == 8'd18) | extended_mode & (addr == 8'd24)) & transmit_buffer_status;
-wire we_tx_data_9               = cs & we & (~reset_mode) & ((~extended_mode) & (addr == 8'd19) | extended_mode & (addr == 8'd25)) & transmit_buffer_status;
-wire we_tx_data_10              = cs & we & (~reset_mode) & (                                     extended_mode & (addr == 8'd26)) & transmit_buffer_status;
-wire we_tx_data_11              = cs & we & (~reset_mode) & (                                     extended_mode & (addr == 8'd27)) & transmit_buffer_status;
-wire we_tx_data_12              = cs & we & (~reset_mode) & (                                     extended_mode & (addr == 8'd28)) & transmit_buffer_status;
+wire we_acceptance_code_0       = cs & we &   reset_mode  & ((~extended_mode) & (addr_write == 8'd4)  | extended_mode & (addr_write == 8'd16));
+wire we_acceptance_mask_0       = cs & we &   reset_mode  & ((~extended_mode) & (addr_write == 8'd5)  | extended_mode & (addr_write == 8'd20));
+wire we_tx_data_0               = cs & we & (~reset_mode) & ((~extended_mode) & (addr_write == 8'd10) | extended_mode & (addr_write == 8'd16)) & transmit_buffer_status;
+wire we_tx_data_1               = cs & we & (~reset_mode) & ((~extended_mode) & (addr_write == 8'd11) | extended_mode & (addr_write == 8'd17)) & transmit_buffer_status;
+wire we_tx_data_2               = cs & we & (~reset_mode) & ((~extended_mode) & (addr_write == 8'd12) | extended_mode & (addr_write == 8'd18)) & transmit_buffer_status;
+wire we_tx_data_3               = cs & we & (~reset_mode) & ((~extended_mode) & (addr_write == 8'd13) | extended_mode & (addr_write == 8'd19)) & transmit_buffer_status;
+wire we_tx_data_4               = cs & we & (~reset_mode) & ((~extended_mode) & (addr_write == 8'd14) | extended_mode & (addr_write == 8'd20)) & transmit_buffer_status;
+wire we_tx_data_5               = cs & we & (~reset_mode) & ((~extended_mode) & (addr_write == 8'd15) | extended_mode & (addr_write == 8'd21)) & transmit_buffer_status;
+wire we_tx_data_6               = cs & we & (~reset_mode) & ((~extended_mode) & (addr_write == 8'd16) | extended_mode & (addr_write == 8'd22)) & transmit_buffer_status;
+wire we_tx_data_7               = cs & we & (~reset_mode) & ((~extended_mode) & (addr_write == 8'd17) | extended_mode & (addr_write == 8'd23)) & transmit_buffer_status;
+wire we_tx_data_8               = cs & we & (~reset_mode) & ((~extended_mode) & (addr_write == 8'd18) | extended_mode & (addr_write == 8'd24)) & transmit_buffer_status;
+wire we_tx_data_9               = cs & we & (~reset_mode) & ((~extended_mode) & (addr_write == 8'd19) | extended_mode & (addr_write == 8'd25)) & transmit_buffer_status;
+wire we_tx_data_10              = cs & we & (~reset_mode) & (                                     extended_mode & (addr_write == 8'd26)) & transmit_buffer_status;
+wire we_tx_data_11              = cs & we & (~reset_mode) & (                                     extended_mode & (addr_write == 8'd27)) & transmit_buffer_status;
+wire we_tx_data_12              = cs & we & (~reset_mode) & (                                     extended_mode & (addr_write == 8'd28)) & transmit_buffer_status;
 /* End: This section is for BASIC and EXTENDED mode */
 
 
 /* This section is for EXTENDED mode */
-wire   we_interrupt_enable      = cs & we & (addr == 8'd4)  & extended_mode;
-wire   we_error_warning_limit   = cs & we & (addr == 8'd13) & reset_mode & extended_mode;
-assign we_rx_err_cnt            = cs & we & (addr == 8'd14) & reset_mode & extended_mode;
-assign we_tx_err_cnt            = cs & we & (addr == 8'd15) & reset_mode & extended_mode;
-wire   we_acceptance_code_1     = cs & we & (addr == 8'd17) & reset_mode & extended_mode;
-wire   we_acceptance_code_2     = cs & we & (addr == 8'd18) & reset_mode & extended_mode;
-wire   we_acceptance_code_3     = cs & we & (addr == 8'd19) & reset_mode & extended_mode;
-wire   we_acceptance_mask_1     = cs & we & (addr == 8'd21) & reset_mode & extended_mode;
-wire   we_acceptance_mask_2     = cs & we & (addr == 8'd22) & reset_mode & extended_mode;
-wire   we_acceptance_mask_3     = cs & we & (addr == 8'd23) & reset_mode & extended_mode;
+wire   we_interrupt_enable      = cs & we & (addr_write == 8'd4)  & extended_mode;
+wire   we_error_warning_limit   = cs & we & (addr_write == 8'd13) & reset_mode & extended_mode;
+assign we_rx_err_cnt            = cs & we & (addr_write == 8'd14) & reset_mode & extended_mode;
+assign we_tx_err_cnt            = cs & we & (addr_write == 8'd15) & reset_mode & extended_mode;
+wire   we_acceptance_code_1     = cs & we & (addr_write == 8'd17) & reset_mode & extended_mode;
+wire   we_acceptance_code_2     = cs & we & (addr_write == 8'd18) & reset_mode & extended_mode;
+wire   we_acceptance_code_3     = cs & we & (addr_write == 8'd19) & reset_mode & extended_mode;
+wire   we_acceptance_mask_1     = cs & we & (addr_write == 8'd21) & reset_mode & extended_mode;
+wire   we_acceptance_mask_2     = cs & we & (addr_write == 8'd22) & reset_mode & extended_mode;
+wire   we_acceptance_mask_3     = cs & we & (addr_write == 8'd23) & reset_mode & extended_mode;
 /* End: This section is for EXTENDED mode */
 
 
@@ -1081,7 +1086,7 @@ can_register #(8) ACCEPTANCE_MASK_REG3
 
 
 // Reading data from registers
-always @ ( addr or extended_mode or mode or bus_timing_0 or bus_timing_1 or clock_divider or
+always @ ( addr_read or extended_mode or mode or bus_timing_0 or bus_timing_1 or clock_divider or
            acceptance_code_0 or acceptance_code_1 or acceptance_code_2 or acceptance_code_3 or
            acceptance_mask_0 or acceptance_mask_1 or acceptance_mask_2 or acceptance_mask_3 or
            reset_mode or tx_data_0 or tx_data_1 or tx_data_2 or tx_data_3 or tx_data_4 or 
@@ -1090,7 +1095,7 @@ always @ ( addr or extended_mode or mode or bus_timing_0 or bus_timing_1 or cloc
            arbitration_lost_capture or rx_message_counter or mode_basic or error_capture_code
          )
 begin
-  case({extended_mode, addr[4:0]})  /* synthesis parallel_case */ 
+  case({extended_mode, addr_read[4:0]})  /* synthesis parallel_case */ 
     {1'h1, 5'd00} :  data_out = {4'b0000, mode_ext[3:1], mode[0]};      // extended mode
     {1'h1, 5'd01} :  data_out = 8'h0;                                   // extended mode
     {1'h1, 5'd02} :  data_out = status;                                 // extended mode
index 691b7038ff6790b74ba6fab232aac0152132a5a2..546a598ca90d7cbdb079341b36d7727f2c30f40b 100644 (file)
@@ -215,10 +215,11 @@ module can_top_raw
 (
   // all reg_* ports are in clk_i clock domain
   reg_we_i,
-  reg_cs_i,
+  reg_re_i,
   reg_data_in,
   reg_data_out,
-  reg_addr_i,
+  reg_addr_read_i,
+  reg_addr_write_i,
   reg_rst_i,
 
   clk_i,
@@ -241,12 +242,14 @@ module can_top_raw
 parameter Tp = 1;
 
 input         reg_we_i;
-input         reg_cs_i;
-input   [7:0] reg_addr_i;
+input         reg_re_i;
+input   [7:0] reg_addr_read_i;
+input   [7:0] reg_addr_write_i;
 input   [7:0] reg_data_in;
 output  [7:0] reg_data_out;
 input         reg_rst_i;
 
+reg     [7:0] reg_data_out;
 
 input        clk_i;
 input        rx_i;
@@ -352,8 +355,6 @@ wire   [7:0] tx_data_11;
 wire   [7:0] tx_data_12;
 /* End: Tx data registers */
 
-wire         cs;
-
 /* Output signals from can_btl module */
 wire         sample_point;
 wire         sampled_bit;
@@ -393,23 +394,33 @@ wire         go_error_frame;
 wire         go_tx;
 wire         send_ack;
 
-wire         rst;
-wire         we;
-wire   [7:0] addr;
-wire   [7:0] data_in;
-reg    [7:0] data_out;
 reg          rx_sync_tmp;
 reg          rx_sync;
 
+wire rst;
+wire we;
+wire re;
+wire cs;
+wire [7:0] addr_read;
+wire [7:0] addr_write;
+
+assign rst       = reg_rst_i;
+assign we        = reg_we_i;
+assign re        = reg_re_i;
+assign cs        = 1'b1;
+assign addr_read = reg_addr_read_i;
+assign addr_write = reg_addr_write_i;
+
 /* Connecting can_registers module */
 can_registers i_can_registers
 ( 
   .clk(clk_i),
   .rst(rst),
-  .cs(cs),
+  .re(re),
   .we(we),
-  .addr(addr),
-  .data_in(data_in),
+  .addr_read(addr_read),
+  .addr_write(addr_write),
+  .data_in(reg_data_in),
   .data_out(data_out_regs),
   .irq_n(irq_on),
 
@@ -578,8 +589,8 @@ can_bsp i_can_bsp
   .tx_point(tx_point),
   .hard_sync(hard_sync),
 
-  .addr(addr),
-  .data_in(data_in),
+  .addr(addr_read),
+  .data_in(reg_data_in),
   .data_out(data_out_fifo),
   .fifo_selected(data_out_fifo_selected),
 
@@ -703,9 +714,9 @@ can_bsp i_can_bsp
 
 
 // Multiplexing wb_dat_o from registers and rx fifo
-always @ (extended_mode or addr or reset_mode)
+always @ (extended_mode or addr_read or reset_mode)
 begin
-  if (extended_mode & (~reset_mode) & ((addr >= 8'd16) && (addr <= 8'd28)) | (~extended_mode) & ((addr >= 8'd20) && (addr <= 8'd29)))
+  if (extended_mode & (~reset_mode) & ((addr_read >= 8'd16) && (addr_read <= 8'd28)) | (~extended_mode) & ((addr_read >= 8'd20) && (addr_read <= 8'd29)))
     data_out_fifo_selected = 1'b1;
   else
     data_out_fifo_selected = 1'b0;
@@ -714,12 +725,12 @@ end
 
 always @ (posedge clk_i)
 begin
-  if (cs & (~we))
+  if (cs & re)
     begin
       if (data_out_fifo_selected)
-        data_out <=#Tp data_out_fifo;
+        reg_data_out <=#Tp data_out_fifo;
       else
-        data_out <=#Tp data_out_regs;
+        reg_data_out <=#Tp data_out_regs;
     end
 end
 
@@ -739,11 +750,4 @@ begin
     end
 end
 
-assign rst       = reg_rst_i;
-assign we        = reg_we_i;
-assign addr      = reg_addr_i;
-assign data_in   = reg_data_in;
-assign reg_data_out = data_out;
-assign cs        = reg_cs_i;
-
 endmodule
diff --git a/system/ip/sja1000_1.0/hdl/rw_arbiter.v b/system/ip/sja1000_1.0/hdl/rw_arbiter.v
new file mode 100644 (file)
index 0000000..8803847
--- /dev/null
@@ -0,0 +1,102 @@
+module rw_arbiter #()
+(
+       input wire  S_AXI_ACLK,
+       input wire  S_AXI_ARESETN,
+       output reg read_pending,
+       output reg read_active,
+       output reg write_pending,
+       output reg write_active,
+       output reg read_active_edge,
+       output reg write_active_edge,
+
+       input wire read_finished,
+       input wire write_finished,
+       
+       input wire ready_read_i,
+       input wire ready_write_i
+);
+
+       wire ready_read_edge;
+       wire ready_write_edge;
+       reg  [1:0] ready_read_hist;
+       reg  [1:0] ready_write_hist;
+       assign ready_read_edge = ready_read_hist[0] ^ ready_read_hist[1];
+       assign ready_write_edge = ready_write_hist[0] ^ ready_write_hist[1];
+
+
+    // read/write arbitration
+    always @ (posedge S_AXI_ACLK or negedge S_AXI_ARESETN)
+    begin
+      if (~S_AXI_ARESETN)
+      begin
+        write_pending <= 1'b0;
+        write_active <= 1'b0;
+        read_pending <= 1'b0;
+        read_active <= 1'b0;
+        ready_read_hist <= 2'b00;
+        ready_write_hist <= 2'b00;
+      end
+      else
+      begin
+        ready_read_hist <= {ready_read_hist[0], ready_read_i};
+        ready_write_hist <= {ready_write_hist[0], ready_write_i /*& (S_AXI_WSTRB == 4'b1111)*/};
+
+        /*
+        if(S_AXI_AWVALID & S_AXI_WVALID & (S_AXI_WSTRB != 4'b1111))
+        begin
+          S_AXI_BVALID <= 1;
+          S_AXI_BRESP <= ...;
+        end
+        */
+
+        if (write_active_edge)
+          write_active_edge = 0;
+        if (read_active_edge)
+          read_active_edge = 0;
+
+        if (ready_write_edge)
+        begin
+          if (read_active & ~read_finished)
+            write_pending <= 1;
+          else
+          begin
+            write_active <= 1;
+            write_active_edge = 1;
+          end
+        end
+
+        if (ready_read_edge)
+        begin
+          if (write_active & ~write_finished)
+            read_pending <= 1;
+          else
+          begin
+            read_active <= 1;
+            read_active_edge = 1;
+          end
+        end
+
+        // read finished in previous cycle
+        if (read_finished)
+        begin
+          read_active <= 1'b0;
+          if (write_pending)
+          begin
+            write_active <= 1;
+            write_pending <= 0;
+          end
+        end
+
+        // write finished in previous cycle
+        if (write_finished)
+        begin
+          write_active <= 1'b0;
+          if (read_pending)
+          begin
+            read_active <= 1;
+            read_pending <= 0;
+          end
+        end
+      end
+    end
+endmodule
index 64851fa028759231509041c4967d270f7ff14e00..679cba1ac57892e501a65ad2ef193d3cc474d7f0 100644 (file)
                output wire  s00_axi_rvalid,
                input wire  s00_axi_rready,
 
-               // Ports of Axi Slave Bus Interface S_AXI_INTR
-               /*
-               input wire  s_axi_intr_aclk,
-               input wire  s_axi_intr_aresetn,
-               input wire [C_S_AXI_INTR_ADDR_WIDTH-1 : 0] s_axi_intr_awaddr,
-               input wire [2 : 0] s_axi_intr_awprot,
-               input wire  s_axi_intr_awvalid,
-               output wire  s_axi_intr_awready,
-               input wire [C_S_AXI_INTR_DATA_WIDTH-1 : 0] s_axi_intr_wdata,
-               input wire [(C_S_AXI_INTR_DATA_WIDTH/8)-1 : 0] s_axi_intr_wstrb,
-               input wire  s_axi_intr_wvalid,
-               output wire  s_axi_intr_wready,
-               output wire [1 : 0] s_axi_intr_bresp,
-               output wire  s_axi_intr_bvalid,
-               input wire  s_axi_intr_bready,
-               input wire [C_S_AXI_INTR_ADDR_WIDTH-1 : 0] s_axi_intr_araddr,
-               input wire [2 : 0] s_axi_intr_arprot,
-               input wire  s_axi_intr_arvalid,
-               output wire  s_axi_intr_arready,
-               output wire [C_S_AXI_INTR_DATA_WIDTH-1 : 0] s_axi_intr_rdata,
-               output wire [1 : 0] s_axi_intr_rresp,
-               output wire  s_axi_intr_rvalid,
-               input wire  s_axi_intr_rready,
-               */
                output wire  irq
        );
        wire reg_we;
        wire reg_rst;
        wire [7:0] reg_data_in;
        wire [7:0] reg_data_out;
-       wire [7:0] reg_addr;
+       wire [7:0] reg_addr_read;
+       wire [7:0] reg_addr_write;
        
        wire irq_n;
        assign irq = ~irq_n;
 
 // Instantiation of Axi Bus Interface S00_AXI
-       can_ifc_axi # ( 
+       can_ifc_axi_sync_duplex # ( 
                .C_S_AXI_DATA_WIDTH(C_S00_AXI_DATA_WIDTH),
                .C_S_AXI_ADDR_WIDTH(C_S00_AXI_ADDR_WIDTH)
        ) can_ifc_axi_inst (
                .S_AXI_RVALID(s00_axi_rvalid),
                .S_AXI_RREADY(s00_axi_rready),
                
-               .clk_i(can_clk),
+               //.clk_i(can_clk),
                .reg_rst_o(reg_rst),
-               .reg_cs_o(reg_cs),
+               .reg_re_o(reg_re),
                .reg_we_o(reg_we),
-               .reg_addr_o(reg_addr),
+               .reg_addr_read_o(reg_addr_read),
+               .reg_addr_write_o(reg_addr_write),
                .reg_data_in_o(reg_data_in),
                .reg_data_out_i(reg_data_out)
        );
 
        can_top_raw can_top_raw_inst (
                .reg_we_i(reg_we),
-               .reg_cs_i(reg_cs),
+               .reg_re_i(reg_re),
                .reg_data_in(reg_data_in),
                .reg_data_out(reg_data_out),
-               .reg_addr_i(reg_addr),
+               .reg_addr_read_i(reg_addr_read),
+               .reg_addr_write_i(reg_addr_write),
                .reg_rst_i(reg_rst),
 
                .clk_i(can_clk),
                .clkout_o()
        );
 
-// Instantiation of Axi Bus Interface S_AXI_INTR
-/*
-       SJA1000_v1_0_S_AXI_INTR # ( 
-               .C_S_AXI_DATA_WIDTH(C_S_AXI_INTR_DATA_WIDTH),
-               .C_S_AXI_ADDR_WIDTH(C_S_AXI_INTR_ADDR_WIDTH),
-               .C_NUM_OF_INTR(C_NUM_OF_INTR),
-               .C_INTR_SENSITIVITY(C_INTR_SENSITIVITY),
-               .C_INTR_ACTIVE_STATE(C_INTR_ACTIVE_STATE),
-               .C_IRQ_SENSITIVITY(C_IRQ_SENSITIVITY),
-               .C_IRQ_ACTIVE_STATE(C_IRQ_ACTIVE_STATE)
-       ) SJA1000_v1_0_S_AXI_INTR_inst (
-               .S_AXI_ACLK(s_axi_intr_aclk),
-               .S_AXI_ARESETN(s_axi_intr_aresetn),
-               .S_AXI_AWADDR(s_axi_intr_awaddr),
-               .S_AXI_AWPROT(s_axi_intr_awprot),
-               .S_AXI_AWVALID(s_axi_intr_awvalid),
-               .S_AXI_AWREADY(s_axi_intr_awready),
-               .S_AXI_WDATA(s_axi_intr_wdata),
-               .S_AXI_WSTRB(s_axi_intr_wstrb),
-               .S_AXI_WVALID(s_axi_intr_wvalid),
-               .S_AXI_WREADY(s_axi_intr_wready),
-               .S_AXI_BRESP(s_axi_intr_bresp),
-               .S_AXI_BVALID(s_axi_intr_bvalid),
-               .S_AXI_BREADY(s_axi_intr_bready),
-               .S_AXI_ARADDR(s_axi_intr_araddr),
-               .S_AXI_ARPROT(s_axi_intr_arprot),
-               .S_AXI_ARVALID(s_axi_intr_arvalid),
-               .S_AXI_ARREADY(s_axi_intr_arready),
-               .S_AXI_RDATA(s_axi_intr_rdata),
-               .S_AXI_RRESP(s_axi_intr_rresp),
-               .S_AXI_RVALID(s_axi_intr_rvalid),
-               .S_AXI_RREADY(s_axi_intr_rready),
-               .irq(irq)
-       );*/
-
        // Add user logic here
 
        // User logic ends