Add files via upload

This commit is contained in:
WalkerLau 2020-08-24 16:47:22 +08:00 committed by GitHub
parent bc35eec7cb
commit 00044b6750
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
58 changed files with 170695 additions and 0 deletions

Binary file not shown.

View File

@ -0,0 +1,502 @@
//-----------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from ARM Limited.
//
// (C) COPYRIGHT 2001-2013-2020 ARM Limited.
// ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from ARM Limited.
//
// SVN Information
//
// Checked In : $Date: 2012-10-15 18:01:36 +0100 (Mon, 15 Oct 2012) $
//
// Revision : $Revision: 225465 $
//
// Release Information : Cortex-M System Design Kit-r1p0-01rel0
//
//-----------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
// Abstract : BusMatrix is the top-level which connects together
// the required Input Stages, MatrixDecodes, Output
// Stages and Output Arbitration blocks.
//
// Supports the following configured options:
//
// - Architecture type 'ahb2',
// - 1 slave ports (connecting to masters),
// - 2 master ports (connecting to slaves),
// - Routing address width of 32 bits,
// - Routing data width of 32 bits,
// - xUSER signal width of 32 bits,
// - Arbiter type 'fixed',
// - Connectivity mapping:
// S<0..0> -> M<0..1>,
// - Connectivity type 'full'.
//
//------------------------------------------------------------------------------
`timescale 1ns/1ps
module cmsdk_L1AhbMtx (
// Common AHB signals
HCLK,
HRESETn,
// System address remapping control
REMAP,
// Input port SI0 (inputs from master 0)
HSELS0_SYS,
HADDRS0_SYS,
HTRANSS0_SYS,
HWRITES0_SYS,
HSIZES0_SYS,
HBURSTS0_SYS,
HPROTS0_SYS,
HMASTERS0_SYS,
HWDATAS0_SYS,
HMASTLOCKS0_SYS,
HREADYS0_SYS,
HAUSERS0_SYS,
HWUSERS0_SYS,
// Output port MI0 (inputs from slave 0)
HRDATAM0_DTCM,
HREADYOUTM0_DTCM,
HRESPM0_DTCM,
HRUSERM0_DTCM,
// Output port MI1 (inputs from slave 1)
HRDATAM1_APB_BRIDGE,
HREADYOUTM1_APB_BRIDGE,
HRESPM1_APB_BRIDGE,
HRUSERM1_APB_BRIDGE,
// Scan test dummy signals; not connected until scan insertion
SCANENABLE, // Scan Test Mode Enable
SCANINHCLK, // Scan Chain Input
// Output port MI0 (outputs to slave 0)
HSELM0_DTCM,
HADDRM0_DTCM,
HTRANSM0_DTCM,
HWRITEM0_DTCM,
HSIZEM0_DTCM,
HBURSTM0_DTCM,
HPROTM0_DTCM,
HMASTERM0_DTCM,
HWDATAM0_DTCM,
HMASTLOCKM0_DTCM,
HREADYMUXM0_DTCM,
HAUSERM0_DTCM,
HWUSERM0_DTCM,
// Output port MI1 (outputs to slave 1)
HSELM1_APB_BRIDGE,
HADDRM1_APB_BRIDGE,
HTRANSM1_APB_BRIDGE,
HWRITEM1_APB_BRIDGE,
HSIZEM1_APB_BRIDGE,
HBURSTM1_APB_BRIDGE,
HPROTM1_APB_BRIDGE,
HMASTERM1_APB_BRIDGE,
HWDATAM1_APB_BRIDGE,
HMASTLOCKM1_APB_BRIDGE,
HREADYMUXM1_APB_BRIDGE,
HAUSERM1_APB_BRIDGE,
HWUSERM1_APB_BRIDGE,
// Input port SI0 (outputs to master 0)
HRDATAS0_SYS,
HREADYOUTS0_SYS,
HRESPS0_SYS,
HRUSERS0_SYS,
// Scan test dummy signals; not connected until scan insertion
SCANOUTHCLK // Scan Chain Output
);
// -----------------------------------------------------------------------------
// Input and Output declarations
// -----------------------------------------------------------------------------
// Common AHB signals
input HCLK; // AHB System Clock
input HRESETn; // AHB System Reset
// System address remapping control
input [3:0] REMAP; // REMAP input
// Input port SI0 (inputs from master 0)
input HSELS0_SYS; // Slave Select
input [31:0] HADDRS0_SYS; // Address bus
input [1:0] HTRANSS0_SYS; // Transfer type
input HWRITES0_SYS; // Transfer direction
input [2:0] HSIZES0_SYS; // Transfer size
input [2:0] HBURSTS0_SYS; // Burst type
input [3:0] HPROTS0_SYS; // Protection control
input [3:0] HMASTERS0_SYS; // Master select
input [31:0] HWDATAS0_SYS; // Write data
input HMASTLOCKS0_SYS; // Locked Sequence
input HREADYS0_SYS; // Transfer done
input [31:0] HAUSERS0_SYS; // Address USER signals
input [31:0] HWUSERS0_SYS; // Write-data USER signals
// Output port MI0 (inputs from slave 0)
input [31:0] HRDATAM0_DTCM; // Read data bus
input HREADYOUTM0_DTCM; // HREADY feedback
input [1:0] HRESPM0_DTCM; // Transfer response
input [31:0] HRUSERM0_DTCM; // Read-data USER signals
// Output port MI1 (inputs from slave 1)
input [31:0] HRDATAM1_APB_BRIDGE; // Read data bus
input HREADYOUTM1_APB_BRIDGE; // HREADY feedback
input [1:0] HRESPM1_APB_BRIDGE; // Transfer response
input [31:0] HRUSERM1_APB_BRIDGE; // Read-data USER signals
// Scan test dummy signals; not connected until scan insertion
input SCANENABLE; // Scan enable signal
input SCANINHCLK; // HCLK scan input
// Output port MI0 (outputs to slave 0)
output HSELM0_DTCM; // Slave Select
output [31:0] HADDRM0_DTCM; // Address bus
output [1:0] HTRANSM0_DTCM; // Transfer type
output HWRITEM0_DTCM; // Transfer direction
output [2:0] HSIZEM0_DTCM; // Transfer size
output [2:0] HBURSTM0_DTCM; // Burst type
output [3:0] HPROTM0_DTCM; // Protection control
output [3:0] HMASTERM0_DTCM; // Master select
output [31:0] HWDATAM0_DTCM; // Write data
output HMASTLOCKM0_DTCM; // Locked Sequence
output HREADYMUXM0_DTCM; // Transfer done
output [31:0] HAUSERM0_DTCM; // Address USER signals
output [31:0] HWUSERM0_DTCM; // Write-data USER signals
// Output port MI1 (outputs to slave 1)
output HSELM1_APB_BRIDGE; // Slave Select
output [31:0] HADDRM1_APB_BRIDGE; // Address bus
output [1:0] HTRANSM1_APB_BRIDGE; // Transfer type
output HWRITEM1_APB_BRIDGE; // Transfer direction
output [2:0] HSIZEM1_APB_BRIDGE; // Transfer size
output [2:0] HBURSTM1_APB_BRIDGE; // Burst type
output [3:0] HPROTM1_APB_BRIDGE; // Protection control
output [3:0] HMASTERM1_APB_BRIDGE; // Master select
output [31:0] HWDATAM1_APB_BRIDGE; // Write data
output HMASTLOCKM1_APB_BRIDGE; // Locked Sequence
output HREADYMUXM1_APB_BRIDGE; // Transfer done
output [31:0] HAUSERM1_APB_BRIDGE; // Address USER signals
output [31:0] HWUSERM1_APB_BRIDGE; // Write-data USER signals
// Input port SI0 (outputs to master 0)
output [31:0] HRDATAS0_SYS; // Read data bus
output HREADYOUTS0_SYS; // HREADY feedback
output [1:0] HRESPS0_SYS; // Transfer response
output [31:0] HRUSERS0_SYS; // Read-data USER signals
// Scan test dummy signals; not connected until scan insertion
output SCANOUTHCLK; // Scan Chain Output
// -----------------------------------------------------------------------------
// Wire declarations
// -----------------------------------------------------------------------------
// Common AHB signals
wire HCLK; // AHB System Clock
wire HRESETn; // AHB System Reset
// System address remapping control
wire [3:0] REMAP; // REMAP signal
// Input Port SI0
wire HSELS0_SYS; // Slave Select
wire [31:0] HADDRS0_SYS; // Address bus
wire [1:0] HTRANSS0_SYS; // Transfer type
wire HWRITES0_SYS; // Transfer direction
wire [2:0] HSIZES0_SYS; // Transfer size
wire [2:0] HBURSTS0_SYS; // Burst type
wire [3:0] HPROTS0_SYS; // Protection control
wire [3:0] HMASTERS0_SYS; // Master select
wire [31:0] HWDATAS0_SYS; // Write data
wire HMASTLOCKS0_SYS; // Locked Sequence
wire HREADYS0_SYS; // Transfer done
wire [31:0] HRDATAS0_SYS; // Read data bus
wire HREADYOUTS0_SYS; // HREADY feedback
wire [1:0] HRESPS0_SYS; // Transfer response
wire [31:0] HAUSERS0_SYS; // Address USER signals
wire [31:0] HWUSERS0_SYS; // Write-data USER signals
wire [31:0] HRUSERS0_SYS; // Read-data USER signals
// Output Port MI0
wire HSELM0_DTCM; // Slave Select
wire [31:0] HADDRM0_DTCM; // Address bus
wire [1:0] HTRANSM0_DTCM; // Transfer type
wire HWRITEM0_DTCM; // Transfer direction
wire [2:0] HSIZEM0_DTCM; // Transfer size
wire [2:0] HBURSTM0_DTCM; // Burst type
wire [3:0] HPROTM0_DTCM; // Protection control
wire [3:0] HMASTERM0_DTCM; // Master select
wire [31:0] HWDATAM0_DTCM; // Write data
wire HMASTLOCKM0_DTCM; // Locked Sequence
wire HREADYMUXM0_DTCM; // Transfer done
wire [31:0] HRDATAM0_DTCM; // Read data bus
wire HREADYOUTM0_DTCM; // HREADY feedback
wire [1:0] HRESPM0_DTCM; // Transfer response
wire [31:0] HAUSERM0_DTCM; // Address USER signals
wire [31:0] HWUSERM0_DTCM; // Write-data USER signals
wire [31:0] HRUSERM0_DTCM; // Read-data USER signals
// Output Port MI1
wire HSELM1_APB_BRIDGE; // Slave Select
wire [31:0] HADDRM1_APB_BRIDGE; // Address bus
wire [1:0] HTRANSM1_APB_BRIDGE; // Transfer type
wire HWRITEM1_APB_BRIDGE; // Transfer direction
wire [2:0] HSIZEM1_APB_BRIDGE; // Transfer size
wire [2:0] HBURSTM1_APB_BRIDGE; // Burst type
wire [3:0] HPROTM1_APB_BRIDGE; // Protection control
wire [3:0] HMASTERM1_APB_BRIDGE; // Master select
wire [31:0] HWDATAM1_APB_BRIDGE; // Write data
wire HMASTLOCKM1_APB_BRIDGE; // Locked Sequence
wire HREADYMUXM1_APB_BRIDGE; // Transfer done
wire [31:0] HRDATAM1_APB_BRIDGE; // Read data bus
wire HREADYOUTM1_APB_BRIDGE; // HREADY feedback
wire [1:0] HRESPM1_APB_BRIDGE; // Transfer response
wire [31:0] HAUSERM1_APB_BRIDGE; // Address USER signals
wire [31:0] HWUSERM1_APB_BRIDGE; // Write-data USER signals
wire [31:0] HRUSERM1_APB_BRIDGE; // Read-data USER signals
// -----------------------------------------------------------------------------
// Signal declarations
// -----------------------------------------------------------------------------
// Bus-switch input SI0
wire i_sel0; // HSEL signal
wire [31:0] i_addr0; // HADDR signal
wire [1:0] i_trans0; // HTRANS signal
wire i_write0; // HWRITE signal
wire [2:0] i_size0; // HSIZE signal
wire [2:0] i_burst0; // HBURST signal
wire [3:0] i_prot0; // HPROTS signal
wire [3:0] i_master0; // HMASTER signal
wire i_mastlock0; // HMASTLOCK signal
wire i_active0; // Active signal
wire i_held_tran0; // HeldTran signal
wire i_readyout0; // Readyout signal
wire [1:0] i_resp0; // Response signal
wire [31:0] i_auser0; // HAUSER signal
// Bus-switch SI0 to MI0 signals
wire i_sel0to0; // Routing selection signal
wire i_active0to0; // Active signal
// Bus-switch SI0 to MI1 signals
wire i_sel0to1; // Routing selection signal
wire i_active0to1; // Active signal
wire i_hready_mux_m0_dtcm; // Internal HREADYMUXM for MI0
wire i_hready_mux_m1_apb_bridge; // Internal HREADYMUXM for MI1
// -----------------------------------------------------------------------------
// Beginning of main code
// -----------------------------------------------------------------------------
// Input stage for SI0
cmsdk_MyInputName u_cmsdk_MyInputName_0 (
// Common AHB signals
.HCLK (HCLK),
.HRESETn (HRESETn),
// Input Port Address/Control Signals
.HSELS (HSELS0_SYS),
.HADDRS (HADDRS0_SYS),
.HTRANSS (HTRANSS0_SYS),
.HWRITES (HWRITES0_SYS),
.HSIZES (HSIZES0_SYS),
.HBURSTS (HBURSTS0_SYS),
.HPROTS (HPROTS0_SYS),
.HMASTERS (HMASTERS0_SYS),
.HMASTLOCKS (HMASTLOCKS0_SYS),
.HREADYS (HREADYS0_SYS),
.HAUSERS (HAUSERS0_SYS),
// Internal Response
.active_ip (i_active0),
.readyout_ip (i_readyout0),
.resp_ip (i_resp0),
// Input Port Response
.HREADYOUTS (HREADYOUTS0_SYS),
.HRESPS (HRESPS0_SYS),
// Internal Address/Control Signals
.sel_ip (i_sel0),
.addr_ip (i_addr0),
.auser_ip (i_auser0),
.trans_ip (i_trans0),
.write_ip (i_write0),
.size_ip (i_size0),
.burst_ip (i_burst0),
.prot_ip (i_prot0),
.master_ip (i_master0),
.mastlock_ip (i_mastlock0),
.held_tran_ip (i_held_tran0)
);
// Matrix decoder for SI0
cmsdk_MyDecoderNameS0_SYS u_cmsdk_mydecodernames0_sys (
// Common AHB signals
.HCLK (HCLK),
.HRESETn (HRESETn),
// Signals from Input stage SI0
.HREADYS (HREADYS0_SYS),
.sel_dec (i_sel0),
.decode_addr_dec (i_addr0[31:10]), // HADDR[9:0] is not decoded
.trans_dec (i_trans0),
// Control/Response for Output Stage MI0
.active_dec0 (i_active0to0),
.readyout_dec0 (i_hready_mux_m0_dtcm),
.resp_dec0 (HRESPM0_DTCM),
.rdata_dec0 (HRDATAM0_DTCM),
.ruser_dec0 (HRUSERM0_DTCM),
// Control/Response for Output Stage MI1
.active_dec1 (i_active0to1),
.readyout_dec1 (i_hready_mux_m1_apb_bridge),
.resp_dec1 (HRESPM1_APB_BRIDGE),
.rdata_dec1 (HRDATAM1_APB_BRIDGE),
.ruser_dec1 (HRUSERM1_APB_BRIDGE),
.sel_dec0 (i_sel0to0),
.sel_dec1 (i_sel0to1),
.active_dec (i_active0),
.HREADYOUTS (i_readyout0),
.HRESPS (i_resp0),
.HRUSERS (HRUSERS0_SYS),
.HRDATAS (HRDATAS0_SYS)
);
// Output stage for MI0
cmsdk_MyOutputName u_cmsdk_myoutputname_0 (
// Common AHB signals
.HCLK (HCLK),
.HRESETn (HRESETn),
// Port 0 Signals
.sel_op0 (i_sel0to0),
.addr_op0 (i_addr0),
.auser_op0 (i_auser0),
.trans_op0 (i_trans0),
.write_op0 (i_write0),
.size_op0 (i_size0),
.burst_op0 (i_burst0),
.prot_op0 (i_prot0),
.master_op0 (i_master0),
.mastlock_op0 (i_mastlock0),
.wdata_op0 (HWDATAS0_SYS),
.wuser_op0 (HWUSERS0_SYS),
.held_tran_op0 (i_held_tran0),
// Slave read data and response
.HREADYOUTM (HREADYOUTM0_DTCM),
.active_op0 (i_active0to0),
// Slave Address/Control Signals
.HSELM (HSELM0_DTCM),
.HADDRM (HADDRM0_DTCM),
.HAUSERM (HAUSERM0_DTCM),
.HTRANSM (HTRANSM0_DTCM),
.HWRITEM (HWRITEM0_DTCM),
.HSIZEM (HSIZEM0_DTCM),
.HBURSTM (HBURSTM0_DTCM),
.HPROTM (HPROTM0_DTCM),
.HMASTERM (HMASTERM0_DTCM),
.HMASTLOCKM (HMASTLOCKM0_DTCM),
.HREADYMUXM (i_hready_mux_m0_dtcm),
.HWUSERM (HWUSERM0_DTCM),
.HWDATAM (HWDATAM0_DTCM)
);
// Drive output with internal version
assign HREADYMUXM0_DTCM = i_hready_mux_m0_dtcm;
// Output stage for MI1
cmsdk_MyOutputName u_cmsdk_myoutputname_1 (
// Common AHB signals
.HCLK (HCLK),
.HRESETn (HRESETn),
// Port 0 Signals
.sel_op0 (i_sel0to1),
.addr_op0 (i_addr0),
.auser_op0 (i_auser0),
.trans_op0 (i_trans0),
.write_op0 (i_write0),
.size_op0 (i_size0),
.burst_op0 (i_burst0),
.prot_op0 (i_prot0),
.master_op0 (i_master0),
.mastlock_op0 (i_mastlock0),
.wdata_op0 (HWDATAS0_SYS),
.wuser_op0 (HWUSERS0_SYS),
.held_tran_op0 (i_held_tran0),
// Slave read data and response
.HREADYOUTM (HREADYOUTM1_APB_BRIDGE),
.active_op0 (i_active0to1),
// Slave Address/Control Signals
.HSELM (HSELM1_APB_BRIDGE),
.HADDRM (HADDRM1_APB_BRIDGE),
.HAUSERM (HAUSERM1_APB_BRIDGE),
.HTRANSM (HTRANSM1_APB_BRIDGE),
.HWRITEM (HWRITEM1_APB_BRIDGE),
.HSIZEM (HSIZEM1_APB_BRIDGE),
.HBURSTM (HBURSTM1_APB_BRIDGE),
.HPROTM (HPROTM1_APB_BRIDGE),
.HMASTERM (HMASTERM1_APB_BRIDGE),
.HMASTLOCKM (HMASTLOCKM1_APB_BRIDGE),
.HREADYMUXM (i_hready_mux_m1_apb_bridge),
.HWUSERM (HWUSERM1_APB_BRIDGE),
.HWDATAM (HWDATAM1_APB_BRIDGE)
);
// Drive output with internal version
assign HREADYMUXM1_APB_BRIDGE = i_hready_mux_m1_apb_bridge;
endmodule
// --================================= End ===================================--

View File

@ -0,0 +1,138 @@
//-----------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from ARM Limited.
//
// (C) COPYRIGHT 2001-2013-2020 ARM Limited.
// ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from ARM Limited.
//
// SVN Information
//
// Checked In : $Date: 2013-01-23 11:45:45 +0000 (Wed, 23 Jan 2013) $
//
// Revision : $Revision: 234562 $
//
// Release Information : Cortex-M System Design Kit-r1p0-01rel0
//
//-----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
// Abstract : Default slave used to drive the slave response signals
// when there are no other slaves selected.
//-----------------------------------------------------------------------------
`timescale 1ns/1ps
module cmsdk_L1AhbMtx_default_slave (
// Common AHB signals
HCLK,
HRESETn,
// AHB control input signals
HSEL,
HTRANS,
HREADY,
// AHB control output signals
HREADYOUT,
HRESP
);
// -----------------------------------------------------------------------------
// Input and Output declarations
// -----------------------------------------------------------------------------
// Common AHB signals
input HCLK; // AHB System Clock
input HRESETn; // AHB System Reset
// AHB control input signals
input HSEL; // Slave Select
input [1:0] HTRANS; // Transfer type
input HREADY; // Transfer done
// AHB control output signals
output HREADYOUT; // HREADY feedback
output [1:0] HRESP; // Transfer response
// -----------------------------------------------------------------------------
// Constant declarations
// -----------------------------------------------------------------------------
// HRESP transfer response signal encoding
`define RSP_OKAY 2'b00 // OKAY response
`define RSP_ERROR 2'b01 // ERROR response
`define RSP_RETRY 2'b10 // RETRY response
`define RSP_SPLIT 2'b11 // SPLIT response
// -----------------------------------------------------------------------------
// Input and Output declarations
// -----------------------------------------------------------------------------
// Common AHB signals
wire HCLK; // AHB System Clock
wire HRESETn; // AHB System Reset
// AHB control input signals
wire HSEL; // Slave Select
wire [1:0] HTRANS; // Transfer type
wire HREADY; // Transfer done
// AHB control output signals
wire HREADYOUT; // HREADY feedback
wire [1:0] HRESP; // Transfer response
// -----------------------------------------------------------------------------
// Signal declarations
// -----------------------------------------------------------------------------
wire invalid; // Set during invalid transfer
wire hready_next; // Controls generation of HREADYOUT output
reg i_hreadyout; // HREADYOUT register
wire [1:0] hresp_next; // Generated response
reg [1:0] i_hresp; // HRESP register
// -----------------------------------------------------------------------------
// Beginning of main code
// -----------------------------------------------------------------------------
assign invalid = ( HREADY & HSEL & HTRANS[1] );
assign hready_next = i_hreadyout ? ~invalid : 1'b1 ;
assign hresp_next = invalid ? `RSP_ERROR : `RSP_OKAY;
always @(negedge HRESETn or posedge HCLK)
begin : p_resp_seq
if (~HRESETn)
begin
i_hreadyout <= 1'b1;
i_hresp <= `RSP_OKAY;
end
else
begin
i_hreadyout <= hready_next;
if (i_hreadyout)
i_hresp <= hresp_next;
end
end
// Drive outputs with internal versions
assign HREADYOUT = i_hreadyout;
assign HRESP = i_hresp;
endmodule
// --================================= End ===================================--

View File

@ -0,0 +1,353 @@
//-----------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from ARM Limited.
//
// (C) COPYRIGHT 2001-2013-2020 ARM Limited.
// ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from ARM Limited.
//
// SVN Information
//
// Checked In : $Date: 2012-10-15 18:01:36 +0100 (Mon, 15 Oct 2012) $
//
// Revision : $Revision: 225465 $
//
// Release Information : Cortex-M System Design Kit-r1p0-01rel0
//
//-----------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
// Abstract : BusMatrixLite is a wrapper module that wraps around
// the BusMatrix module to give AHB Lite compliant
// slave and master interfaces.
//
//-----------------------------------------------------------------------------
`timescale 1ns/1ps
module cmsdk_L1AhbMtx_lite (
// Common AHB signals
HCLK,
HRESETn,
// System Address Remap control
REMAP,
// Input port SI0 (inputs from master 0)
HADDRS0_SYS,
HTRANSS0_SYS,
HWRITES0_SYS,
HSIZES0_SYS,
HBURSTS0_SYS,
HPROTS0_SYS,
HWDATAS0_SYS,
HMASTLOCKS0_SYS,
HAUSERS0_SYS,
HWUSERS0_SYS,
// Output port MI0 (inputs from slave 0)
HRDATAM0_DTCM,
HREADYOUTM0_DTCM,
HRESPM0_DTCM,
HRUSERM0_DTCM,
// Output port MI1 (inputs from slave 1)
HRDATAM1_APB_BRIDGE,
HREADYOUTM1_APB_BRIDGE,
HRESPM1_APB_BRIDGE,
HRUSERM1_APB_BRIDGE,
// Scan test dummy signals; not connected until scan insertion
SCANENABLE, // Scan Test Mode Enable
SCANINHCLK, // Scan Chain Input
// Output port MI0 (outputs to slave 0)
HSELM0_DTCM,
HADDRM0_DTCM,
HTRANSM0_DTCM,
HWRITEM0_DTCM,
HSIZEM0_DTCM,
HBURSTM0_DTCM,
HPROTM0_DTCM,
HWDATAM0_DTCM,
HMASTLOCKM0_DTCM,
HREADYMUXM0_DTCM,
HAUSERM0_DTCM,
HWUSERM0_DTCM,
// Output port MI1 (outputs to slave 1)
HSELM1_APB_BRIDGE,
HADDRM1_APB_BRIDGE,
HTRANSM1_APB_BRIDGE,
HWRITEM1_APB_BRIDGE,
HSIZEM1_APB_BRIDGE,
HBURSTM1_APB_BRIDGE,
HPROTM1_APB_BRIDGE,
HWDATAM1_APB_BRIDGE,
HMASTLOCKM1_APB_BRIDGE,
HREADYMUXM1_APB_BRIDGE,
HAUSERM1_APB_BRIDGE,
HWUSERM1_APB_BRIDGE,
// Input port SI0 (outputs to master 0)
HRDATAS0_SYS,
HREADYS0_SYS,
HRESPS0_SYS,
HRUSERS0_SYS,
// Scan test dummy signals; not connected until scan insertion
SCANOUTHCLK // Scan Chain Output
);
// -----------------------------------------------------------------------------
// Input and Output declarations
// -----------------------------------------------------------------------------
// Common AHB signals
input HCLK; // AHB System Clock
input HRESETn; // AHB System Reset
// System Address Remap control
input [3:0] REMAP; // System Address REMAP control
// Input port SI0 (inputs from master 0)
input [31:0] HADDRS0_SYS; // Address bus
input [1:0] HTRANSS0_SYS; // Transfer type
input HWRITES0_SYS; // Transfer direction
input [2:0] HSIZES0_SYS; // Transfer size
input [2:0] HBURSTS0_SYS; // Burst type
input [3:0] HPROTS0_SYS; // Protection control
input [31:0] HWDATAS0_SYS; // Write data
input HMASTLOCKS0_SYS; // Locked Sequence
input [31:0] HAUSERS0_SYS; // Address USER signals
input [31:0] HWUSERS0_SYS; // Write-data USER signals
// Output port MI0 (inputs from slave 0)
input [31:0] HRDATAM0_DTCM; // Read data bus
input HREADYOUTM0_DTCM; // HREADY feedback
input HRESPM0_DTCM; // Transfer response
input [31:0] HRUSERM0_DTCM; // Read-data USER signals
// Output port MI1 (inputs from slave 1)
input [31:0] HRDATAM1_APB_BRIDGE; // Read data bus
input HREADYOUTM1_APB_BRIDGE; // HREADY feedback
input HRESPM1_APB_BRIDGE; // Transfer response
input [31:0] HRUSERM1_APB_BRIDGE; // Read-data USER signals
// Scan test dummy signals; not connected until scan insertion
input SCANENABLE; // Scan enable signal
input SCANINHCLK; // HCLK scan input
// Output port MI0 (outputs to slave 0)
output HSELM0_DTCM; // Slave Select
output [31:0] HADDRM0_DTCM; // Address bus
output [1:0] HTRANSM0_DTCM; // Transfer type
output HWRITEM0_DTCM; // Transfer direction
output [2:0] HSIZEM0_DTCM; // Transfer size
output [2:0] HBURSTM0_DTCM; // Burst type
output [3:0] HPROTM0_DTCM; // Protection control
output [31:0] HWDATAM0_DTCM; // Write data
output HMASTLOCKM0_DTCM; // Locked Sequence
output HREADYMUXM0_DTCM; // Transfer done
output [31:0] HAUSERM0_DTCM; // Address USER signals
output [31:0] HWUSERM0_DTCM; // Write-data USER signals
// Output port MI1 (outputs to slave 1)
output HSELM1_APB_BRIDGE; // Slave Select
output [31:0] HADDRM1_APB_BRIDGE; // Address bus
output [1:0] HTRANSM1_APB_BRIDGE; // Transfer type
output HWRITEM1_APB_BRIDGE; // Transfer direction
output [2:0] HSIZEM1_APB_BRIDGE; // Transfer size
output [2:0] HBURSTM1_APB_BRIDGE; // Burst type
output [3:0] HPROTM1_APB_BRIDGE; // Protection control
output [31:0] HWDATAM1_APB_BRIDGE; // Write data
output HMASTLOCKM1_APB_BRIDGE; // Locked Sequence
output HREADYMUXM1_APB_BRIDGE; // Transfer done
output [31:0] HAUSERM1_APB_BRIDGE; // Address USER signals
output [31:0] HWUSERM1_APB_BRIDGE; // Write-data USER signals
// Input port SI0 (outputs to master 0)
output [31:0] HRDATAS0_SYS; // Read data bus
output HREADYS0_SYS; // HREADY feedback
output HRESPS0_SYS; // Transfer response
output [31:0] HRUSERS0_SYS; // Read-data USER signals
// Scan test dummy signals; not connected until scan insertion
output SCANOUTHCLK; // Scan Chain Output
// -----------------------------------------------------------------------------
// Wire declarations
// -----------------------------------------------------------------------------
// Common AHB signals
wire HCLK; // AHB System Clock
wire HRESETn; // AHB System Reset
// System Address Remap control
wire [3:0] REMAP; // System REMAP signal
// Input Port SI0
wire [31:0] HADDRS0_SYS; // Address bus
wire [1:0] HTRANSS0_SYS; // Transfer type
wire HWRITES0_SYS; // Transfer direction
wire [2:0] HSIZES0_SYS; // Transfer size
wire [2:0] HBURSTS0_SYS; // Burst type
wire [3:0] HPROTS0_SYS; // Protection control
wire [31:0] HWDATAS0_SYS; // Write data
wire HMASTLOCKS0_SYS; // Locked Sequence
wire [31:0] HRDATAS0_SYS; // Read data bus
wire HREADYS0_SYS; // HREADY feedback
wire HRESPS0_SYS; // Transfer response
wire [31:0] HAUSERS0_SYS; // Address USER signals
wire [31:0] HWUSERS0_SYS; // Write-data USER signals
wire [31:0] HRUSERS0_SYS; // Read-data USER signals
// Output Port MI0
wire HSELM0_DTCM; // Slave Select
wire [31:0] HADDRM0_DTCM; // Address bus
wire [1:0] HTRANSM0_DTCM; // Transfer type
wire HWRITEM0_DTCM; // Transfer direction
wire [2:0] HSIZEM0_DTCM; // Transfer size
wire [2:0] HBURSTM0_DTCM; // Burst type
wire [3:0] HPROTM0_DTCM; // Protection control
wire [31:0] HWDATAM0_DTCM; // Write data
wire HMASTLOCKM0_DTCM; // Locked Sequence
wire HREADYMUXM0_DTCM; // Transfer done
wire [31:0] HRDATAM0_DTCM; // Read data bus
wire HREADYOUTM0_DTCM; // HREADY feedback
wire HRESPM0_DTCM; // Transfer response
wire [31:0] HAUSERM0_DTCM; // Address USER signals
wire [31:0] HWUSERM0_DTCM; // Write-data USER signals
wire [31:0] HRUSERM0_DTCM; // Read-data USER signals
// Output Port MI1
wire HSELM1_APB_BRIDGE; // Slave Select
wire [31:0] HADDRM1_APB_BRIDGE; // Address bus
wire [1:0] HTRANSM1_APB_BRIDGE; // Transfer type
wire HWRITEM1_APB_BRIDGE; // Transfer direction
wire [2:0] HSIZEM1_APB_BRIDGE; // Transfer size
wire [2:0] HBURSTM1_APB_BRIDGE; // Burst type
wire [3:0] HPROTM1_APB_BRIDGE; // Protection control
wire [31:0] HWDATAM1_APB_BRIDGE; // Write data
wire HMASTLOCKM1_APB_BRIDGE; // Locked Sequence
wire HREADYMUXM1_APB_BRIDGE; // Transfer done
wire [31:0] HRDATAM1_APB_BRIDGE; // Read data bus
wire HREADYOUTM1_APB_BRIDGE; // HREADY feedback
wire HRESPM1_APB_BRIDGE; // Transfer response
wire [31:0] HAUSERM1_APB_BRIDGE; // Address USER signals
wire [31:0] HWUSERM1_APB_BRIDGE; // Write-data USER signals
wire [31:0] HRUSERM1_APB_BRIDGE; // Read-data USER signals
// -----------------------------------------------------------------------------
// Signal declarations
// -----------------------------------------------------------------------------
wire [3:0] tie_hi_4;
wire tie_hi;
wire tie_low;
wire [1:0] i_hrespS0_SYS;
wire [3:0] i_hmasterM0_DTCM;
wire [1:0] i_hrespM0_DTCM;
wire [3:0] i_hmasterM1_APB_BRIDGE;
wire [1:0] i_hrespM1_APB_BRIDGE;
// -----------------------------------------------------------------------------
// Beginning of main code
// -----------------------------------------------------------------------------
assign tie_hi = 1'b1;
assign tie_hi_4 = 4'b1111;
assign tie_low = 1'b0;
assign HRESPS0_SYS = i_hrespS0_SYS[0];
assign i_hrespM0_DTCM = {tie_low, HRESPM0_DTCM};
assign i_hrespM1_APB_BRIDGE = {tie_low, HRESPM1_APB_BRIDGE};
// BusMatrix instance
cmsdk_L1AhbMtx ucmsdk_L1AhbMtx (
.HCLK (HCLK),
.HRESETn (HRESETn),
.REMAP (REMAP),
// Input port SI0 signals
.HSELS0_SYS (tie_hi),
.HADDRS0_SYS (HADDRS0_SYS),
.HTRANSS0_SYS (HTRANSS0_SYS),
.HWRITES0_SYS (HWRITES0_SYS),
.HSIZES0_SYS (HSIZES0_SYS),
.HBURSTS0_SYS (HBURSTS0_SYS),
.HPROTS0_SYS (HPROTS0_SYS),
.HWDATAS0_SYS (HWDATAS0_SYS),
.HMASTLOCKS0_SYS (HMASTLOCKS0_SYS),
.HMASTERS0_SYS (tie_hi_4),
.HREADYS0_SYS (HREADYS0_SYS),
.HAUSERS0_SYS (HAUSERS0_SYS),
.HWUSERS0_SYS (HWUSERS0_SYS),
.HRDATAS0_SYS (HRDATAS0_SYS),
.HREADYOUTS0_SYS (HREADYS0_SYS),
.HRESPS0_SYS (i_hrespS0_SYS),
.HRUSERS0_SYS (HRUSERS0_SYS),
// Output port MI0 signals
.HSELM0_DTCM (HSELM0_DTCM),
.HADDRM0_DTCM (HADDRM0_DTCM),
.HTRANSM0_DTCM (HTRANSM0_DTCM),
.HWRITEM0_DTCM (HWRITEM0_DTCM),
.HSIZEM0_DTCM (HSIZEM0_DTCM),
.HBURSTM0_DTCM (HBURSTM0_DTCM),
.HPROTM0_DTCM (HPROTM0_DTCM),
.HWDATAM0_DTCM (HWDATAM0_DTCM),
.HMASTERM0_DTCM (i_hmasterM0_DTCM),
.HMASTLOCKM0_DTCM (HMASTLOCKM0_DTCM),
.HREADYMUXM0_DTCM (HREADYMUXM0_DTCM),
.HAUSERM0_DTCM (HAUSERM0_DTCM),
.HWUSERM0_DTCM (HWUSERM0_DTCM),
.HRDATAM0_DTCM (HRDATAM0_DTCM),
.HREADYOUTM0_DTCM (HREADYOUTM0_DTCM),
.HRESPM0_DTCM (i_hrespM0_DTCM),
.HRUSERM0_DTCM (HRUSERM0_DTCM),
// Output port MI1 signals
.HSELM1_APB_BRIDGE (HSELM1_APB_BRIDGE),
.HADDRM1_APB_BRIDGE (HADDRM1_APB_BRIDGE),
.HTRANSM1_APB_BRIDGE (HTRANSM1_APB_BRIDGE),
.HWRITEM1_APB_BRIDGE (HWRITEM1_APB_BRIDGE),
.HSIZEM1_APB_BRIDGE (HSIZEM1_APB_BRIDGE),
.HBURSTM1_APB_BRIDGE (HBURSTM1_APB_BRIDGE),
.HPROTM1_APB_BRIDGE (HPROTM1_APB_BRIDGE),
.HWDATAM1_APB_BRIDGE (HWDATAM1_APB_BRIDGE),
.HMASTERM1_APB_BRIDGE (i_hmasterM1_APB_BRIDGE),
.HMASTLOCKM1_APB_BRIDGE (HMASTLOCKM1_APB_BRIDGE),
.HREADYMUXM1_APB_BRIDGE (HREADYMUXM1_APB_BRIDGE),
.HAUSERM1_APB_BRIDGE (HAUSERM1_APB_BRIDGE),
.HWUSERM1_APB_BRIDGE (HWUSERM1_APB_BRIDGE),
.HRDATAM1_APB_BRIDGE (HRDATAM1_APB_BRIDGE),
.HREADYOUTM1_APB_BRIDGE (HREADYOUTM1_APB_BRIDGE),
.HRESPM1_APB_BRIDGE (i_hrespM1_APB_BRIDGE),
.HRUSERM1_APB_BRIDGE (HRUSERM1_APB_BRIDGE),
// Scan test dummy signals; not connected until scan insertion
.SCANENABLE (SCANENABLE),
.SCANINHCLK (SCANINHCLK),
.SCANOUTHCLK (SCANOUTHCLK)
);
endmodule

View File

@ -0,0 +1,159 @@
//-----------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from ARM Limited.
//
// (C) COPYRIGHT 2001-2013-2020 ARM Limited.
// ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from ARM Limited.
//
// SVN Information
//
// Checked In : $Date: 2012-10-15 18:01:36 +0100 (Mon, 15 Oct 2012) $
//
// Revision : $Revision: 225465 $
//
// Release Information : Cortex-M System Design Kit-r1p0-01rel0
//
//-----------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
// Abstract : The Output Arbitration is used to determine which
// of the input stages will be given access to the
// shared slave.
//
// Notes : The bus matrix has full connectivity.
//
//-----------------------------------------------------------------------------
`timescale 1ns/1ps
module cmsdk_MyArbiterName (
// Common AHB signals
HCLK ,
HRESETn,
// Input port request signals
req_port0,
HREADYM,
HSELM,
HTRANSM,
HBURSTM,
HMASTLOCKM,
// Arbiter outputs
addr_in_port,
no_port
);
// -----------------------------------------------------------------------------
// Input and Output declarations
// -----------------------------------------------------------------------------
// Common AHB signals
input HCLK; // AHB system clock
input HRESETn; // AHB system reset
input req_port0; // Port 0 request signal
input HREADYM; // Transfer done
input HSELM; // Slave select line
input [1:0] HTRANSM; // Transfer type
input [2:0] HBURSTM; // Burst type
input HMASTLOCKM; // Locked transfer
output [0:0] addr_in_port; // Port address input
output no_port; // No port selected signal
// -----------------------------------------------------------------------------
// Wire declarations
// -----------------------------------------------------------------------------
wire HCLK; // AHB system clock
wire HRESETn; // AHB system reset
wire req_port0; // Port 0 request signal
wire HREADYM; // Transfer done
wire HSELM; // Slave select line
wire [1:0] HTRANSM; // Transfer type
wire HMASTLOCKM; // Locked transfer
wire [0:0] addr_in_port; // Port address input
reg no_port; // No port selected signal
// -----------------------------------------------------------------------------
// Signal declarations
// -----------------------------------------------------------------------------
reg [0:0] addr_in_port_next; // D-input of addr_in_port
reg [0:0] iaddr_in_port; // Internal version of addr_in_port
reg no_port_next; // D-input of no_port
// -----------------------------------------------------------------------------
// Beginning of main code
// -----------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Port Selection
//------------------------------------------------------------------------------
// The Output Arbitration function looks at all the requests to use the
// output port and determines which is the highest priority request. This
// version of the arbitration logic uses a fixed priority scheme where input
// port 0 is the highest priority, input port 1 is the second highest
// priority, etc.
// If none of the input ports are requesting then the current port will
// remain active if it is performing IDLE transfers to the selected slave. If
// this is not the case then the no_port signal will be asserted which
// indicates that no input port should be selected.
always @ (
req_port0 or
HSELM or HTRANSM or HMASTLOCKM or iaddr_in_port
)
begin : p_sel_port_comb
// Default values are used for addr_in_port_next and no_port_next
no_port_next = 1'b0;
addr_in_port_next = iaddr_in_port;
if (HMASTLOCKM)
addr_in_port_next = iaddr_in_port;
else if ( req_port0 | ( (iaddr_in_port == 1'b0) & HSELM &
(HTRANSM != 2'b00) ) )
addr_in_port_next = 1'b0;
else if (HSELM)
addr_in_port_next = iaddr_in_port;
else
no_port_next = 1'b1;
end // block: p_sel_port_comb
// Sequential process
always @ (negedge HRESETn or posedge HCLK)
begin : p_addr_in_port_reg
if (~HRESETn)
begin
no_port <= 1'b1;
iaddr_in_port <= {1{1'b0}};
end
else
if (HREADYM)
begin
no_port <= no_port_next;
iaddr_in_port <= addr_in_port_next;
end
end // block: p_addr_in_port_reg
// Drive output with internal version
assign addr_in_port = iaddr_in_port;
endmodule
// --================================= End ===================================--

View File

@ -0,0 +1,341 @@
//-----------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from ARM Limited.
//
// (C) COPYRIGHT 2001-2013-2020 ARM Limited.
// ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from ARM Limited.
//
// SVN Information
//
// Checked In : $Date: 2013-01-23 11:45:45 +0000 (Wed, 23 Jan 2013) $
//
// Revision : $Revision: 234562 $
//
// Release Information : Cortex-M System Design Kit-r1p0-01rel0
//
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
// Abstract : The MatrixDecode is used to determine which output
// stage is required for a particular access. Addresses
// that do not map to an Output port are diverted to
// the local default slave.
//
// Notes : The bus matrix has full connectivity.
//
//-----------------------------------------------------------------------------
`timescale 1ns/1ps
module cmsdk_MyDecoderNameS0_SYS (
// Common AHB signals
HCLK,
HRESETn,
// Signals from the Input stage
HREADYS,
sel_dec,
decode_addr_dec,
trans_dec,
// Bus-switch output 0
active_dec0,
readyout_dec0,
resp_dec0,
rdata_dec0,
ruser_dec0,
// Bus-switch output 1
active_dec1,
readyout_dec1,
resp_dec1,
rdata_dec1,
ruser_dec1,
// Output port selection signals
sel_dec0,
sel_dec1,
// Selected Output port data and control signals
active_dec,
HREADYOUTS,
HRESPS,
HRUSERS,
HRDATAS
);
// -----------------------------------------------------------------------------
// Input and Output declarations
// -----------------------------------------------------------------------------
// Common AHB signals
input HCLK; // AHB System Clock
input HRESETn; // AHB System Reset
// Signals from the Input stage
input HREADYS; // Transfer done
input sel_dec; // HSEL input
input [31:10] decode_addr_dec; // HADDR decoder input
input [1:0] trans_dec; // Input port HTRANS signal
// Bus-switch output MI0
input active_dec0; // Output stage MI0 active_dec signal
input readyout_dec0; // HREADYOUT input
input [1:0] resp_dec0; // HRESP input
input [31:0] rdata_dec0; // HRDATA input
input [31:0] ruser_dec0; // HRUSER input
// Bus-switch output MI1
input active_dec1; // Output stage MI1 active_dec signal
input readyout_dec1; // HREADYOUT input
input [1:0] resp_dec1; // HRESP input
input [31:0] rdata_dec1; // HRDATA input
input [31:0] ruser_dec1; // HRUSER input
// Output port selection signals
output sel_dec0; // HSEL output
output sel_dec1; // HSEL output
// Selected Output port data and control signals
output active_dec; // Combinatorial active_dec O/P
output HREADYOUTS; // HREADY feedback output
output [1:0] HRESPS; // Transfer response
output [31:0] HRUSERS; // User read Data
output [31:0] HRDATAS; // Read Data
// -----------------------------------------------------------------------------
// Wire declarations
// -----------------------------------------------------------------------------
// Common AHB signals
wire HCLK; // AHB System Clock
wire HRESETn; // AHB System Reset
// Signals from the Input stage
wire HREADYS; // Transfer done
wire sel_dec; // HSEL input
wire [31:10] decode_addr_dec; // HADDR input
wire [1:0] trans_dec; // Input port HTRANS signal
// Bus-switch output MI0
wire active_dec0; // active_dec signal
wire readyout_dec0; // HREADYOUT input
wire [1:0] resp_dec0; // HRESP input
wire [31:0] rdata_dec0; // HRDATA input
wire [31:0] ruser_dec0; // HRUSER input
reg sel_dec0; // HSEL output
// Bus-switch output MI1
wire active_dec1; // active_dec signal
wire readyout_dec1; // HREADYOUT input
wire [1:0] resp_dec1; // HRESP input
wire [31:0] rdata_dec1; // HRDATA input
wire [31:0] ruser_dec1; // HRUSER input
reg sel_dec1; // HSEL output
// -----------------------------------------------------------------------------
// Signal declarations
// -----------------------------------------------------------------------------
// Selected Output port data and control signals
reg active_dec; // Combinatorial active_dec O/P signal
reg HREADYOUTS; // Combinatorial HREADYOUT signal
reg [1:0] HRESPS; // Combinatorial HRESPS signal
reg [31:0] HRUSERS;
reg [31:0] HRDATAS; // Read data bus
reg [1:0] addr_out_port; // Address output ports
reg [1:0] data_out_port; // Data output ports
// Default slave signals
reg sel_dft_slv; // HSEL signal
wire readyout_dft_slv; // HREADYOUT signal
wire [1:0] resp_dft_slv; // Combinatorial HRESPS signal
// -----------------------------------------------------------------------------
// Beginning of main code
// -----------------------------------------------------------------------------
//------------------------------------------------------------------------------
// Default slave (accessed when HADDR is unmapped)
//------------------------------------------------------------------------------
cmsdk_L1AhbMtx_default_slave u_cmsdk_L1AhbMtx_default_slave (
// Common AHB signals
.HCLK (HCLK),
.HRESETn (HRESETn),
// AHB Control signals
.HSEL (sel_dft_slv),
.HTRANS (trans_dec),
.HREADY (HREADYS),
.HREADYOUT (readyout_dft_slv),
.HRESP (resp_dft_slv)
);
//------------------------------------------------------------------------------
// Address phase signals
//------------------------------------------------------------------------------
// The address decode is done in two stages. This is so that the address
// decode occurs in only one process, p_addr_out_portComb, and then the select
// signal is factored in.
//
// Note that the hexadecimal address values are reformatted to align with the
// lower bound of decode_addr_dec[31:10], which is not a hex character boundary
always @ (
decode_addr_dec or data_out_port or trans_dec
)
begin : p_addr_out_port_comb
// Address region 0x20000000-0x3fffffff
if (((decode_addr_dec >= 22'h080000) & (decode_addr_dec <= 22'h0fffff))
| ((data_out_port == 2'b00) & (trans_dec == 2'b00)))
addr_out_port = 2'b00; // Select Output port MI0
// Address region 0x40000000-0x4fffffff
else if (((decode_addr_dec >= 22'h100000) & (decode_addr_dec <= 22'h13ffff))
| ((data_out_port == 2'b01) & (trans_dec == 2'b00)))
addr_out_port = 2'b01; // Select Output port MI1
else
addr_out_port = 2'b10; // Select the default slave
end // block: p_addr_out_port_comb
// Select signal decode
always @ (sel_dec or addr_out_port)
begin : p_sel_comb
sel_dec0 = 1'b0;
sel_dec1 = 1'b0;
sel_dft_slv = 1'b0;
if (sel_dec)
case (addr_out_port)
2'b00 : sel_dec0 = 1'b1;
2'b01 : sel_dec1 = 1'b1;
2'b10 : sel_dft_slv = 1'b1; // Select the default slave
default : begin
sel_dec0 = 1'bx;
sel_dec1 = 1'bx;
sel_dft_slv = 1'bx;
end
endcase // case(addr_out_port)
end // block: p_sel_comb
// The decoder selects the appropriate active_dec signal depending on which
// output stage is required for the transfer.
always @ (
active_dec0 or
active_dec1 or
addr_out_port
)
begin : p_active_comb
case (addr_out_port)
2'b00 : active_dec = active_dec0;
2'b01 : active_dec = active_dec1;
2'b10 : active_dec = 1'b1; // Select the default slave
default : active_dec = 1'bx;
endcase // case(addr_out_port)
end // block: p_active_comb
//------------------------------------------------------------------------------
// Data phase signals
//------------------------------------------------------------------------------
// The data_out_port needs to be updated when HREADY from the input stage is high.
// Note: HREADY must be used, not HREADYOUT, because there are occaisions
// (namely when the holding register gets loaded) when HREADYOUT may be low
// but HREADY is high, and in this case it is important that the data_out_port
// gets updated.
always @ (negedge HRESETn or posedge HCLK)
begin : p_data_out_port_seq
if (~HRESETn)
data_out_port <= {2{1'b0}};
else
if (HREADYS)
data_out_port <= addr_out_port;
end // block: p_data_out_port_seq
// HREADYOUTS output decode
always @ (
readyout_dft_slv or
readyout_dec0 or
readyout_dec1 or
data_out_port
)
begin : p_ready_comb
case (data_out_port)
2'b00 : HREADYOUTS = readyout_dec0;
2'b01 : HREADYOUTS = readyout_dec1;
2'b10 : HREADYOUTS = readyout_dft_slv; // Select the default slave
default : HREADYOUTS = 1'bx;
endcase // case(data_out_port)
end // block: p_ready_comb
// HRESPS output decode
always @ (
resp_dft_slv or
resp_dec0 or
resp_dec1 or
data_out_port
)
begin : p_resp_comb
case (data_out_port)
2'b00 : HRESPS = resp_dec0;
2'b01 : HRESPS = resp_dec1;
2'b10 : HRESPS = resp_dft_slv; // Select the default slave
default : HRESPS = {2{1'bx}};
endcase // case (data_out_port)
end // block: p_resp_comb
// HRDATAS output decode
always @ (
rdata_dec0 or
rdata_dec1 or
data_out_port
)
begin : p_rdata_comb
case (data_out_port)
2'b00 : HRDATAS = rdata_dec0;
2'b01 : HRDATAS = rdata_dec1;
2'b10 : HRDATAS = {32{1'b0}}; // Select the default slave
default : HRDATAS = {32{1'bx}};
endcase // case (data_out_port)
end // block: p_rdata_comb
// HRUSERS output decode
always @ (
ruser_dec0 or
ruser_dec1 or
data_out_port
)
begin : p_ruser_comb
case (data_out_port)
2'b00 : HRUSERS = ruser_dec0;
2'b01 : HRUSERS = ruser_dec1;
2'b10 : HRUSERS = {32{1'b0}}; // Select the default slave
default : HRUSERS = {32{1'bx}};
endcase // case (data_out_port)
end // block: p_ruser_comb
endmodule
// --================================= End ===================================--

View File

@ -0,0 +1,471 @@
//-----------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from ARM Limited.
//
// (C) COPYRIGHT 2001-2013-2020 ARM Limited.
// ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from ARM Limited.
//
// SVN Information
//
// Checked In : $Date: 2012-10-15 18:01:36 +0100 (Mon, 15 Oct 2012) $
//
// Revision : $Revision: 225465 $
//
// Release Information : Cortex-M System Design Kit-r1p0-01rel0
//
//-----------------------------------------------------------------------------
//
//------------------------------------------------------------------------------
// Abstract : The Input Stage is used to hold a pending transfer
// when the required output stage is not available.
//
//-----------------------------------------------------------------------------
`timescale 1ns/1ps
module cmsdk_MyInputName (
// Common AHB signals
HCLK,
HRESETn,
// Input Port Address/Control Signals
HSELS,
HADDRS,
HAUSERS,
HTRANSS,
HWRITES,
HSIZES,
HBURSTS,
HPROTS,
HMASTERS,
HMASTLOCKS,
HREADYS,
// Internal Response
active_ip,
readyout_ip,
resp_ip,
// Input Port Response
HREADYOUTS,
HRESPS,
// Internal Address/Control Signals
sel_ip,
addr_ip,
auser_ip,
trans_ip,
write_ip,
size_ip,
burst_ip,
prot_ip,
master_ip,
mastlock_ip,
held_tran_ip
);
// -----------------------------------------------------------------------------
// Input and Output declarations
// -----------------------------------------------------------------------------
input HCLK; // AHB System Clock
input HRESETn; // AHB System Reset
input HSELS; // Slave Select from AHB
input [31:0] HADDRS; // Address bus from AHB
input [31:0] HAUSERS; // Additional user adress bus
input [1:0] HTRANSS; // Transfer type from AHB
input HWRITES; // Transfer direction from AHB
input [2:0] HSIZES; // Transfer size from AHB
input [2:0] HBURSTS; // Burst type from AHB
input [3:0] HPROTS; // Protection control from AHB
input [3:0] HMASTERS; // Master number from AHB
input HMASTLOCKS; // Locked Sequence from AHB
input HREADYS; // Transfer done from AHB
input active_ip; // active_ip signal
input readyout_ip; // HREADYOUT input
input [1:0] resp_ip; // HRESP input
output HREADYOUTS; // HREADY feedback to AHB
output [1:0] HRESPS; // Transfer response to AHB
output sel_ip; // HSEL output
output [31:0] addr_ip; // HADDR output
output [31:0] auser_ip; // HAUSER output
output [1:0] trans_ip; // HTRANS output
output write_ip; // HWRITE output
output [2:0] size_ip; // HSIZE output
output [2:0] burst_ip; // HBURST output
output [3:0] prot_ip; // HPROT output
output [3:0] master_ip; // HMASTER output
output mastlock_ip; // HMASTLOCK output
output held_tran_ip; // Holding register active flag
// -----------------------------------------------------------------------------
// Constant declarations
// -----------------------------------------------------------------------------
// HTRANS transfer type signal encoding
`define TRN_IDLE 2'b00 // Idle Transfer
`define TRN_BUSY 2'b01 // Busy Transfer
`define TRN_NONSEQ 2'b10 // Nonsequential transfer
`define TRN_SEQ 2'b11 // Sequential transfer
// HBURST transfer type signal encoding
`define BUR_SINGLE 3'b000 // Single BURST
`define BUR_INCR 3'b001 // Incremental BURSTS
`define BUR_WRAP4 3'b010 // 4-beat wrap
`define BUR_INCR4 3'b011 // 4-beat incr
`define BUR_WRAP8 3'b100 // 8-beat wrap
`define BUR_INCR8 3'b101 // 8-beat incr
`define BUR_WRAP16 3'b110 // 16-beat wrap
`define BUR_INCR16 3'b111 // 16-beat incr
// HRESP signal encoding
`define RSP_OKAY 2'b00 // OKAY response
`define RSP_ERROR 2'b01 // ERROR response
`define RSP_RETRY 2'b10 // RETRY response
`define RSP_SPLIT 2'b11 // SPLIT response
// -----------------------------------------------------------------------------
// Wire declarations
// -----------------------------------------------------------------------------
wire HCLK; // AHB System Clock
wire HRESETn; // AHB System Reset
wire HSELS; // Slave Select from AHB
wire [31:0] HADDRS; // Address bus from AHB
wire [31:0] HAUSERS; // Additional user adress bus
wire [1:0] HTRANSS; // Transfer type from AHB
wire HWRITES; // Transfer direction from AHB
wire [2:0] HSIZES; // Transfer size from AHB
wire [2:0] HBURSTS; // Burst type from AHB
wire [3:0] HPROTS; // Protection control from AHB
wire [3:0] HMASTERS; // Master number from AHB
wire HMASTLOCKS; // Locked Sequence from AHB
wire HREADYS; // Transfer done from AHB
reg HREADYOUTS; // HREADY feedback to AHB
reg [1:0] HRESPS; // Transfer response to AHB
reg sel_ip; // HSEL output
reg [31:0] addr_ip; // HADDR output
reg [31:0] auser_ip; // HAUSER output
wire [1:0] trans_ip; // HTRANS output
reg write_ip; // HWRITE output
reg [2:0] size_ip; // HSIZE output
wire [2:0] burst_ip; // HBURST output
reg [3:0] prot_ip; // HPROT output
reg [3:0] master_ip; // HMASTER output
reg mastlock_ip; // HMASTLOCK output
wire held_tran_ip; // Holding register active flag
wire active_ip; // active_ip signal
wire readyout_ip; // HREADYOUT input
wire [1:0] resp_ip; // HRESP input
// -----------------------------------------------------------------------------
// Signal declarations
// -----------------------------------------------------------------------------
wire load_reg; // Holding register load flag
wire pend_tran; // An active transfer cannot complete
reg pend_tran_reg; // Registered version of pend_tran
wire addr_valid; // Indicates address phase of
// valid transfer
reg data_valid; // Indicates data phase of
// valid transfer
reg [1:0] reg_trans; // Registered HTRANSS
reg [31:0] reg_addr; // Registered HADDRS
reg [31:0] reg_auser;
reg reg_write; // Registered HWRITES
reg [2:0] reg_size; // Registered HSIZES
reg [2:0] reg_burst; // Registered HBURSTS
reg [3:0] reg_prot; // Registered HPROTS
reg [3:0] reg_master; // Registerd HMASTERS
reg reg_mastlock; // Registered HMASTLOCKS
reg [1:0] transb; // HTRANS output used for burst information
reg [1:0] trans_int; // HTRANS output
reg [2:0] burst_int; // HBURST output
reg [3:0] offset_addr; // Address offset for boundary logic
reg [3:0] check_addr; // Address check for wrapped bursts
reg burst_override; // Registered burst_override_next
wire burst_override_next; // Indicates burst has been over-ridden
reg bound; // Registered version of bound_next
wire bound_next; // Indicates boundary wrapping
wire bound_en; // Clock-enable for bound register
// -----------------------------------------------------------------------------
// Beginning of main code
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Holding Registers
// -----------------------------------------------------------------------------
// Each input port has a holding register associated with it and a mux to
// select between the register and the direct input path. The control of
// the mux is done simply by selecting the holding register when it is loaded
// with a pending transfer, otherwise the straight through path is used.
always @ (negedge HRESETn or posedge HCLK)
begin : p_holding_reg_seq1
if (~HRESETn)
begin
reg_trans <= 2'b00;
reg_addr <= {32{1'b0}};
reg_auser <= {32{1'b0}};
reg_write <= 1'b0 ;
reg_size <= 3'b000;
reg_burst <= 3'b000;
reg_prot <= {4{1'b0}};
reg_master <= 4'b0000;
reg_mastlock <= 1'b0 ;
end
else
if (load_reg)
begin
reg_trans <= HTRANSS;
reg_addr <= HADDRS;
reg_auser <= HAUSERS;
reg_write <= HWRITES;
reg_size <= HSIZES;
reg_burst <= HBURSTS;
reg_prot <= HPROTS;
reg_master <= HMASTERS;
reg_mastlock <= HMASTLOCKS;
end
end
// addr_valid indicates the address phase of an active (non-BUSY/IDLE)
// transfer to this slave port
assign addr_valid = ( HSELS & HTRANSS[1] );
// The holding register is loaded whenever there is a transfer on the input
// port which is validated by active HREADYS
assign load_reg = ( addr_valid & HREADYS );
// data_valid register
// addr_valid indicates the data phase of an active (non-BUSY/IDLE)
// transfer to this slave port. A valid response (HREADY, HRESP) must be
// generated
always @ (negedge HRESETn or posedge HCLK)
begin : p_data_valid
if (~HRESETn)
data_valid <= 1'b0;
else
if (HREADYS)
data_valid <= addr_valid;
end
// -----------------------------------------------------------------------------
// Generate HeldTran
// -----------------------------------------------------------------------------
// The HeldTran signal is used to indicate when there is an active transfer
// being presented to the output stage, either passing straight through or from
// the holding register.
// pend_tran indicates that an active transfer presented to this
// slave cannot complete immediately. It is always set after the
// load_reg signal has been active. When set, it is cleared when the
// transfer is being driven onto the selected slave (as indicated by
// active_ip being high) and HREADY from the selected slave is high.
assign pend_tran = (load_reg & (~active_ip)) ? 1'b1 :
(active_ip & readyout_ip) ? 1'b0 : pend_tran_reg;
// pend_tran_reg indicates that an active transfer was accepted by the input
// stage,but not by the output stage, and so the holding registers should be
// used
always @ (negedge HRESETn or posedge HCLK)
begin : p_pend_tran_reg
if (~HRESETn)
pend_tran_reg <= 1'b0;
else
pend_tran_reg <= pend_tran;
end
// held_tran_ip indicates an active transfer, and is held whilst that transfer is
// in the holding registers. It passes to the output stage where it acts as
// a request line to the arbitration scheme
assign held_tran_ip = (load_reg | pend_tran_reg);
// The output from this stage is selected from the holding register when
// there is a held transfer. Otherwise the direct path is used.
always @ ( pend_tran_reg or HSELS or HTRANSS or HADDRS or HWRITES or
HSIZES or HBURSTS or HPROTS or HMASTERS or HMASTLOCKS or
HAUSERS or reg_auser or
reg_addr or reg_write or reg_size or reg_burst or reg_prot or
reg_master or reg_mastlock
)
begin : p_mux_comb
if (~pend_tran_reg)
begin
sel_ip = HSELS;
trans_int = HTRANSS;
addr_ip = HADDRS;
auser_ip = HAUSERS;
write_ip = HWRITES;
size_ip = HSIZES;
burst_int = HBURSTS;
prot_ip = HPROTS;
master_ip = HMASTERS;
mastlock_ip = HMASTLOCKS;
end
else
begin
sel_ip = 1'b1;
trans_int = `TRN_NONSEQ;
addr_ip = reg_addr;
auser_ip = reg_auser;
write_ip = reg_write;
size_ip = reg_size;
burst_int = reg_burst;
prot_ip = reg_prot;
master_ip = reg_master;
mastlock_ip = reg_mastlock;
end
end
// The transb output is used to select the correct Burst value when completing
// an interrupted defined-lenght burst.
always @ (pend_tran_reg or HTRANSS or reg_trans)
begin : p_transb_comb
if (~pend_tran_reg)
transb = HTRANSS;
else
transb = reg_trans;
end // block: p_transb_comb
// Convert SEQ->NONSEQ and BUSY->IDLE when an address boundary is crossed
// whilst the burst type is being over-ridden, i.e. when completing an
// interrupted wrapping burst.
assign trans_ip = (burst_override & bound) ? {trans_int[1], 1'b0}
: trans_int;
assign burst_ip = (burst_override & (transb != `TRN_NONSEQ)) ? `BUR_INCR
: burst_int;
// -----------------------------------------------------------------------------
// HREADYOUT Generation
// -----------------------------------------------------------------------------
// There are three possible sources for the HREADYOUT signal.
// - It is driven LOW when there is a held transfer.
// - It is driven HIGH when not Selected or for Idle/Busy transfers.
// - At all other times it is driven from the appropriate shared
// slave.
always @ (data_valid or pend_tran_reg or readyout_ip or resp_ip)
begin : p_ready_comb
if (~data_valid)
begin
HREADYOUTS = 1'b1;
HRESPS = `RSP_OKAY;
end
else if (pend_tran_reg)
begin
HREADYOUTS = 1'b0;
HRESPS = `RSP_OKAY;
end
else
begin
HREADYOUTS = readyout_ip;
HRESPS = resp_ip;
end
end // block: p_ready_comb
// -----------------------------------------------------------------------------
// Early Burst Termination
// -----------------------------------------------------------------------------
// There are times when the output stage will switch to another input port
// without allowing the current burst to complete. In these cases the HTRANS
// and HBURST signals need to be overriden to ensure that the transfers
// reaching the output port meet the AHB specification.
assign burst_override_next = ( (HTRANSS == `TRN_NONSEQ) |
(HTRANSS == `TRN_IDLE) ) ? 1'b0
: ( (HTRANSS ==`TRN_SEQ) &
load_reg &
(~active_ip) ) ? 1'b1
: burst_override;
// burst_override register
always @ (negedge HRESETn or posedge HCLK)
begin : p_burst_overrideseq
if (~HRESETn)
burst_override <= 1'b0;
else
if (HREADYS)
burst_override <= burst_override_next;
end // block: p_burst_overrideseq
// -----------------------------------------------------------------------------
// Boundary Checking Logic
// -----------------------------------------------------------------------------
// offset_addr
always @ (HADDRS or HSIZES)
begin : p_offset_addr_comb
case (HSIZES)
3'b000 : offset_addr = HADDRS[3:0];
3'b001 : offset_addr = HADDRS[4:1];
3'b010 : offset_addr = HADDRS[5:2];
3'b011 : offset_addr = HADDRS[6:3];
3'b100, 3'b101, 3'b110, 3'b111 :
offset_addr = HADDRS[3:0]; // Sizes >= 128-bits are not supported
default : offset_addr = 4'bxxxx;
endcase
end
// check_addr
always @ (offset_addr or HBURSTS)
begin : p_check_addr_comb
case (HBURSTS)
`BUR_WRAP4 : begin
check_addr[1:0] = offset_addr[1:0];
check_addr[3:2] = 2'b11;
end
`BUR_WRAP8 : begin
check_addr[2:0] = offset_addr[2:0];
check_addr[3] = 1'b1;
end
`BUR_WRAP16 :
check_addr[3:0] = offset_addr[3:0];
`BUR_SINGLE, `BUR_INCR, `BUR_INCR4, `BUR_INCR8, `BUR_INCR16 :
check_addr[3:0] = 4'b0000;
default : check_addr[3:0] = 4'bxxxx;
endcase
end
assign bound_next = ( check_addr == 4'b1111 );
assign bound_en = ( HTRANSS[1] & HREADYS );
// bound register
always @ (negedge HRESETn or posedge HCLK)
begin : p_bound_seq
if (~HRESETn)
bound <= 1'b0;
else
if (bound_en)
bound <= bound_next;
end
endmodule
// --================================= End ===================================--

View File

@ -0,0 +1,379 @@
//-----------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from ARM Limited.
//
// (C) COPYRIGHT 2001-2013-2020 ARM Limited.
// ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from ARM Limited.
//
// SVN Information
//
// Checked In : $Date: 2012-10-15 18:01:36 +0100 (Mon, 15 Oct 2012) $
//
// Revision : $Revision: 225465 $
//
// Release Information : Cortex-M System Design Kit-r1p0-01rel0
//
//-----------------------------------------------------------------------------
//
//-----------------------------------------------------------------------------
// Abstract : The Output Stage is used to route the required input
// stage to the shared slave output.
//
// Notes : The bus matrix has full connectivity,
// and has a fixed arbiter scheme.
//
//-----------------------------------------------------------------------------
`timescale 1ns/1ps
module cmsdk_MyOutputName (
// Common AHB signals
HCLK,
HRESETn,
// Port 0 Signals
sel_op0,
addr_op0,
auser_op0,
trans_op0,
write_op0,
size_op0,
burst_op0,
prot_op0,
master_op0,
mastlock_op0,
wdata_op0,
wuser_op0,
held_tran_op0,
// Slave read data and response
HREADYOUTM,
active_op0,
// Slave Address/Control Signals
HSELM,
HADDRM,
HAUSERM,
HTRANSM,
HWRITEM,
HSIZEM,
HBURSTM,
HPROTM,
HMASTERM,
HMASTLOCKM,
HREADYMUXM,
HWUSERM,
HWDATAM
);
// -----------------------------------------------------------------------------
// Input and Output declarations
// -----------------------------------------------------------------------------
// Common AHB signals
input HCLK; // AHB system clock
input HRESETn; // AHB system reset
// Bus-switch input 0
input sel_op0; // Port 0 HSEL signal
input [31:0] addr_op0; // Port 0 HADDR signal
input [31:0] auser_op0; // Port 0 HAUSER signal
input [1:0] trans_op0; // Port 0 HTRANS signal
input write_op0; // Port 0 HWRITE signal
input [2:0] size_op0; // Port 0 HSIZE signal
input [2:0] burst_op0; // Port 0 HBURST signal
input [3:0] prot_op0; // Port 0 HPROT signal
input [3:0] master_op0; // Port 0 HMASTER signal
input mastlock_op0; // Port 0 HMASTLOCK signal
input [31:0] wdata_op0; // Port 0 HWDATA signal
input [31:0] wuser_op0; // Port 0 HWUSER signal
input held_tran_op0; // Port 0 HeldTran signal
input HREADYOUTM; // HREADY feedback
output active_op0; // Port 0 Active signal
// Slave Address/Control Signals
output HSELM; // Slave select line
output [31:0] HADDRM; // Address
output [31:0] HAUSERM; // User Address bus
output [1:0] HTRANSM; // Transfer type
output HWRITEM; // Transfer direction
output [2:0] HSIZEM; // Transfer size
output [2:0] HBURSTM; // Burst type
output [3:0] HPROTM; // Protection control
output [3:0] HMASTERM; // Master ID
output HMASTLOCKM; // Locked transfer
output HREADYMUXM; // Transfer done
output [31:0] HWUSERM; // User data bus
output [31:0] HWDATAM; // Write data
// -----------------------------------------------------------------------------
// Wire declarations
// -----------------------------------------------------------------------------
wire HCLK; // AHB system clock
wire HRESETn; // AHB system reset
// Bus-switch input 0
wire sel_op0; // Port 0 HSEL signal
wire [31:0] addr_op0; // Port 0 HADDR signal
wire [31:0] auser_op0; // Port 0 HAUSER signal
wire [1:0] trans_op0; // Port 0 HTRANS signal
wire write_op0; // Port 0 HWRITE signal
wire [2:0] size_op0; // Port 0 HSIZE signal
wire [2:0] burst_op0; // Port 0 HBURST signal
wire [3:0] prot_op0; // Port 0 HPROT signal
wire [3:0] master_op0; // Port 0 HMASTER signal
wire mastlock_op0; // Port 0 HMASTLOCK signal
wire [31:0] wdata_op0; // Port 0 HWDATA signal
wire [31:0] wuser_op0; // Port 0 HWUSER signal
wire held_tran_op0; // Port 0 HeldTran signal
reg active_op0; // Port 0 Active signal
// Slave Address/Control Signals
wire HSELM; // Slave select line
reg [31:0] HADDRM; // Address
reg [31:0] HAUSERM; // User Address bus
wire [1:0] HTRANSM; // Transfer type
reg HWRITEM; // Transfer direction
reg [2:0] HSIZEM; // Transfer size
wire [2:0] HBURSTM; // Burst type
reg [3:0] HPROTM; // Protection control
reg [3:0] HMASTERM; // Master ID
wire HMASTLOCKM; // Locked transfer
wire HREADYMUXM; // Transfer done
reg [31:0] HWUSERM; // User data bus
reg [31:0] HWDATAM; // Write data
wire HREADYOUTM; // HREADY feedback
// -----------------------------------------------------------------------------
// Signal declarations
// -----------------------------------------------------------------------------
wire req_port0; // Port 0 request signal
wire [0:0] addr_in_port; // Address input port
reg [0:0] data_in_port; // Data input port
wire no_port; // No port selected signal
reg slave_sel; // Slave select signal
reg hsel_lock; // Held HSELS during locked sequence
wire next_hsel_lock; // Pre-registered hsel_lock
wire hlock_arb; // HMASTLOCK modified by HSEL for arbitration
reg i_hselm; // Internal HSELM
reg [1:0] i_htransm; // Internal HTRANSM
reg [2:0] i_hburstm; // Internal HBURSTM
wire i_hreadymuxm; // Internal HREADYMUXM
reg i_hmastlockm; // Internal HMASTLOCKM
// -----------------------------------------------------------------------------
// Beginning of main code
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// Port Selection
// -----------------------------------------------------------------------------
assign req_port0 = held_tran_op0 & sel_op0;
// Arbiter instance for resolving requests to this output stage
cmsdk_MyArbiterName u_output_arb (
.HCLK (HCLK),
.HRESETn (HRESETn),
.req_port0 (req_port0),
.HREADYM (i_hreadymuxm),
.HSELM (i_hselm),
.HTRANSM (i_htransm),
.HBURSTM (i_hburstm),
.HMASTLOCKM (hlock_arb),
.addr_in_port (addr_in_port),
.no_port (no_port)
);
// Active signal combinatorial decode
always @ (addr_in_port or no_port)
begin : p_active_comb
// Default value(s)
active_op0 = 1'b0;
// Decode selection when enabled
if (~no_port)
case (addr_in_port)
1'b0 : active_op0 = 1'b1;
default : begin
active_op0 = 1'bx;
end
endcase // case(addr_in_port)
end // block: p_active_comb
// Address/control output decode
always @ (
sel_op0 or addr_op0 or trans_op0 or write_op0 or
size_op0 or burst_op0 or prot_op0 or
auser_op0 or
master_op0 or mastlock_op0 or
addr_in_port or no_port
)
begin : p_addr_mux
// Default values
i_hselm = 1'b0;
HADDRM = {32{1'b0}};
HAUSERM = {32{1'b0}};
i_htransm = 2'b00;
HWRITEM = 1'b0;
HSIZEM = 3'b000;
i_hburstm = 3'b000;
HPROTM = {4{1'b0}};
HMASTERM = 4'b0000;
i_hmastlockm= 1'b0;
// Decode selection when enabled
if (~no_port)
case (addr_in_port)
// Bus-switch input 0
1'b0 :
begin
i_hselm = sel_op0;
HADDRM = addr_op0;
HAUSERM = auser_op0;
i_htransm = trans_op0;
HWRITEM = write_op0;
HSIZEM = size_op0;
i_hburstm = burst_op0;
HPROTM = prot_op0;
HMASTERM = master_op0;
i_hmastlockm= mastlock_op0;
end // case: 4'b0
default :
begin
i_hselm = 1'bx;
HADDRM = {32{1'bx}};
HAUSERM = {32{1'bx}};
i_htransm = 2'bxx;
HWRITEM = 1'bx;
HSIZEM = 3'bxxx;
i_hburstm = 3'bxxx;
HPROTM = {4{1'bx}};
HMASTERM = 4'bxxxx;
i_hmastlockm= 1'bx;
end // case: default
endcase // case(addr_in_port)
end // block: p_addr_mux
// hsel_lock provides support for AHB masters that address other
// slave regions in the middle of a locked sequence (i.e. HSEL is
// de-asserted during the locked sequence). Unless HMASTLOCK is
// held during these intermediate cycles, the OutputArb scheme will
// lose track of the locked sequence and may allow another input
// port to access the output port which should be locked
assign next_hsel_lock = (i_hselm & i_htransm[1] & i_hmastlockm) ? 1'b1 :
(i_hmastlockm == 1'b0) ? 1'b0 :
hsel_lock;
// Register hsel_lock
always @ (negedge HRESETn or posedge HCLK)
begin : p_hsel_lock
if (~HRESETn)
hsel_lock <= 1'b0;
else
if (i_hreadymuxm)
hsel_lock <= next_hsel_lock;
end
// Version of HMASTLOCK which is masked when not selected, unless a
// locked sequence has already begun through this port
assign hlock_arb = i_hmastlockm & (hsel_lock | i_hselm);
assign HTRANSM = i_htransm;
assign HBURSTM = i_hburstm;
assign HSELM = i_hselm;
assign HMASTLOCKM = i_hmastlockm;
// Dataport register
always @ (negedge HRESETn or posedge HCLK)
begin : p_data_in_port_reg
if (~HRESETn)
data_in_port <= {1{1'b0}};
else
if (i_hreadymuxm)
data_in_port <= addr_in_port;
end
// HWDATAM output decode
always @ (
wdata_op0 or
data_in_port
)
begin : p_data_mux
// Default value
HWDATAM = {32{1'b0}};
// Decode selection
case (data_in_port)
1'b0 : HWDATAM = wdata_op0;
default : HWDATAM = {32{1'bx}};
endcase // case(data_in_port)
end // block: p_data_mux
// HWUSERM output decode
always @ (
wuser_op0 or
data_in_port
)
begin : p_wuser_mux
// Default value
HWUSERM = {32{1'b0}};
// Decode selection
case (data_in_port)
1'b0 : HWUSERM = wuser_op0;
default : HWUSERM = {32{1'bx}};
endcase // case(data_in_port)
end // block: p_wuser_mux
// ---------------------------------------------------------------------------
// HREADYMUXM generation
// ---------------------------------------------------------------------------
// The HREADY signal on the shared slave is generated directly from
// the shared slave HREADYOUTS if the slave is selected, otherwise
// it mirrors the HREADY signal of the appropriate input port
always @ (negedge HRESETn or posedge HCLK)
begin : p_slave_sel_reg
if (~HRESETn)
slave_sel <= 1'b0;
else
if (i_hreadymuxm)
slave_sel <= i_hselm;
end
// HREADYMUXM output selection
assign i_hreadymuxm = (slave_sel) ? HREADYOUTM : 1'b1;
// Drive output with internal version of the signal
assign HREADYMUXM = i_hreadymuxm;
endmodule
// --================================= End ===================================--

View File

@ -0,0 +1,436 @@
//-----------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from ARM Limited.
//
// (C) COPYRIGHT 2010-2013 ARM Limited.
// ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from ARM Limited.
//
// SVN Information
//
// Checked In : $Date: 2012-10-18 17:09:33 +0100 (Thu, 18 Oct 2012) $
//
// Revision : $Revision: 225826 $
//
// Release Information : Cortex-M System Design Kit-r1p0-00rel0
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Abstract : Simple AHB to APB bridge
//-----------------------------------------------------------------------------
// The bridge requires PCLK synchronised to HCLK
// APB running at a clock divided from HCLK. E.g.
// - If PCLK is same as HCLK, set PCLKEN to 1
// - If PCLK is half the HCLK speed, toggle PCLKEN every HCLK cycle
module cmsdk_ahb_to_apb #(
// Parameter to define address width
// 16 = 2^16 = 64KB APB address space
parameter ADDRWIDTH = 16,
parameter REGISTER_RDATA = 1,
parameter REGISTER_WDATA = 0)
(
// --------------------------------------------------------------------------
// Port Definitions
// --------------------------------------------------------------------------
input wire HCLK, // Clock
input wire HRESETn, // Reset
input wire PCLKEN, // APB clock enable signal
input wire HSEL, // Device select
input wire [ADDRWIDTH-1:0] HADDR, // Address
input wire [1:0] HTRANS, // Transfer control
input wire [2:0] HSIZE, // Transfer size
input wire [3:0] HPROT, // Protection control
input wire HWRITE, // Write control
input wire HREADY, // Transfer phase done
input wire [31:0] HWDATA, // Write data
output reg HREADYOUT, // Device ready
output wire [31:0] HRDATA, // Read data output
output wire HRESP, // Device response
// APB Output
output wire [ADDRWIDTH-1:0] PADDR, // APB Address
output wire PENABLE, // APB Enable
output wire PWRITE, // APB Write
output wire [3:0] PSTRB, // APB Byte Strobe
output wire [2:0] PPROT, // APB Prot
output wire [31:0] PWDATA, // APB write data
output wire PSEL, // APB Select
output wire APBACTIVE, // APB bus is active, for clock gating
// of APB bus
// APB Input
input wire [31:0] PRDATA, // Read data for each APB slave
input wire PREADY, // Ready for each APB slave
input wire PSLVERR); // Error state for each APB slave
// --------------------------------------------------------------------------
// Internal wires
// --------------------------------------------------------------------------
reg [ADDRWIDTH-3:0] addr_reg; // Address sample register
reg wr_reg; // Write control sample register
reg [2:0] state_reg; // State for finite state machine
reg [3:0] pstrb_reg; // Byte lane strobe register
wire [3:0] pstrb_nxt; // Byte lane strobe next state
reg [1:0] pprot_reg; // PPROT register
wire [1:0] pprot_nxt; // PPROT register next state
wire apb_select; // APB bridge is selected
wire apb_tran_end; // Transfer is completed on APB
reg [2:0] next_state; // Next state for finite state machine
reg [31:0] rwdata_reg; // Read/Write data sample register
wire reg_rdata_cfg; // REGISTER_RDATA paramater
wire reg_wdata_cfg; // REGISTER_WDATA paramater
reg sample_wdata_reg; // Control signal to sample HWDATA
// -------------------------------------------------------------------------
// State machine
// -------------------------------------------------------------------------
localparam ST_BITS = 3;
localparam [ST_BITS-1:0] ST_IDLE = 3'b000; // Idle waiting for transaction
localparam [ST_BITS-1:0] ST_APB_WAIT = 3'b001; // Wait APB transfer
localparam [ST_BITS-1:0] ST_APB_TRNF = 3'b010; // Start APB transfer
localparam [ST_BITS-1:0] ST_APB_TRNF2 = 3'b011; // Second APB transfer cycle
localparam [ST_BITS-1:0] ST_APB_ENDOK = 3'b100; // Ending cycle for OKAY
localparam [ST_BITS-1:0] ST_APB_ERR1 = 3'b101; // First cycle for Error response
localparam [ST_BITS-1:0] ST_APB_ERR2 = 3'b110; // Second cycle for Error response
localparam [ST_BITS-1:0] ST_ILLEGAL = 3'b111; // Illegal state
// --------------------------------------------------------------------------
// Start of main code
// --------------------------------------------------------------------------
// Configuration signal
assign reg_rdata_cfg = (REGISTER_RDATA==0) ? 1'b0 : 1'b1;
assign reg_wdata_cfg = (REGISTER_WDATA==0) ? 1'b0 : 1'b1;
// Generate APB bridge select
assign apb_select = HSEL & HTRANS[1] & HREADY;
// Generate APB transfer ended
assign apb_tran_end = (state_reg==3'b011) & PREADY;
assign pprot_nxt[0] = HPROT[1]; // (0) Normal, (1) Privileged
assign pprot_nxt[1] = ~HPROT[0]; // (0) Data, (1) Instruction
// Byte strobe generation
// - Only enable for write operations
// - For word write transfers (HSIZE[1]=1), all byte strobes are 1
// - For hword write transfers (HSIZE[0]=1), check HADDR[1]
// - For byte write transfers, check HADDR[1:0]
assign pstrb_nxt[0] = HWRITE & ((HSIZE[1])|((HSIZE[0])&(~HADDR[1]))|(HADDR[1:0]==2'b00));
assign pstrb_nxt[1] = HWRITE & ((HSIZE[1])|((HSIZE[0])&(~HADDR[1]))|(HADDR[1:0]==2'b01));
assign pstrb_nxt[2] = HWRITE & ((HSIZE[1])|((HSIZE[0])&( HADDR[1]))|(HADDR[1:0]==2'b10));
assign pstrb_nxt[3] = HWRITE & ((HSIZE[1])|((HSIZE[0])&( HADDR[1]))|(HADDR[1:0]==2'b11));
// Sample control signals
always @(posedge HCLK or negedge HRESETn)
begin
if (~HRESETn)
begin
addr_reg <= {(ADDRWIDTH-2){1'b0}};
wr_reg <= 1'b0;
pprot_reg <= {2{1'b0}};
pstrb_reg <= {4{1'b0}};
end
else if (apb_select) // Capture transfer information at the end of AHB address phase
begin
addr_reg <= HADDR[ADDRWIDTH-1:2];
wr_reg <= HWRITE;
pprot_reg <= pprot_nxt;
pstrb_reg <= pstrb_nxt;
end
end
// Sample write data control signal
// Assert after write address phase, deassert after PCLKEN=1
wire sample_wdata_set = apb_select & HWRITE & reg_wdata_cfg;
wire sample_wdata_clr = sample_wdata_reg & PCLKEN;
always @(posedge HCLK or negedge HRESETn)
begin
if (~HRESETn)
sample_wdata_reg <= 1'b0;
else if (sample_wdata_set | sample_wdata_clr)
sample_wdata_reg <= sample_wdata_set;
end
// Generate next state for FSM
// Note : case 3'b111 is not used. The design has been checked that
// this illegal state cannot be entered using formal verification.
always @(state_reg or PREADY or PSLVERR or apb_select or reg_rdata_cfg or
PCLKEN or reg_wdata_cfg or HWRITE)
begin
case (state_reg)
// Idle
ST_IDLE :
begin
if (PCLKEN & apb_select & ~(reg_wdata_cfg & HWRITE))
next_state = ST_APB_TRNF; // Start APB transfer in next cycle
else if (apb_select)
next_state = ST_APB_WAIT; // Wait for start of APB transfer at PCLKEN high
else
next_state = ST_IDLE; // Remain idle
end
// Transfer announced on AHB, but PCLKEN was low, so waiting
ST_APB_WAIT :
begin
if (PCLKEN)
next_state = ST_APB_TRNF; // Start APB transfer in next cycle
else
next_state = ST_APB_WAIT; // Wait for start of APB transfer at PCLKEN high
end
// First APB transfer cycle
ST_APB_TRNF :
begin
if (PCLKEN)
next_state = ST_APB_TRNF2; // Change to second cycle of APB transfer
else
next_state = ST_APB_TRNF; // Change to state-2
end
// Second APB transfer cycle
ST_APB_TRNF2 :
begin
if (PREADY & PSLVERR & PCLKEN) // Error received - Generate two cycle
// Error response on AHB by
next_state = ST_APB_ERR1; // Changing to state-5 and 6
else if (PREADY & (~PSLVERR) & PCLKEN) // Okay received
begin
if (reg_rdata_cfg)
// Registered version
next_state = ST_APB_ENDOK; // Generate okay response in state 4
else
// Non-registered version
next_state = {2'b00, apb_select}; // Terminate transfer
end
else // Slave not ready
next_state = ST_APB_TRNF2; // Unchange
end
// Ending cycle for OKAY (registered response)
ST_APB_ENDOK :
begin
if (PCLKEN & apb_select & ~(reg_wdata_cfg & HWRITE))
next_state = ST_APB_TRNF; // Start APB transfer in next cycle
else if (apb_select)
next_state = ST_APB_WAIT; // Wait for start of APB transfer at PCLKEN high
else
next_state = ST_IDLE; // Remain idle
end
// First cycle for Error response
ST_APB_ERR1 : next_state = ST_APB_ERR2; // Goto 2nd cycle of error response
// Second cycle for Error response
ST_APB_ERR2 :
begin
if (PCLKEN & apb_select & ~(reg_wdata_cfg & HWRITE))
next_state = ST_APB_TRNF; // Start APB transfer in next cycle
else if (apb_select)
next_state = ST_APB_WAIT; // Wait for start of APB transfer at PCLKEN high
else
next_state = ST_IDLE; // Remain idle
end
default : // Not used
next_state = 3'bxxx; // X-Propagation
endcase
end
// Registering state machine
always @(posedge HCLK or negedge HRESETn)
begin
if (~HRESETn)
state_reg <= 3'b000;
else
state_reg <= next_state;
end
// Sample PRDATA or HWDATA
always @(posedge HCLK or negedge HRESETn)
begin
if (~HRESETn)
rwdata_reg <= {32{1'b0}};
else
if (sample_wdata_reg & reg_wdata_cfg & PCLKEN)
rwdata_reg <= HWDATA;
else if (apb_tran_end & reg_rdata_cfg & PCLKEN)
rwdata_reg <= PRDATA;
end
// Connect outputs to top level
assign PADDR = {addr_reg, 2'b00}; // from sample register
assign PWRITE = wr_reg; // from sample register
// From sample register or from HWDATA directly
assign PWDATA = (reg_wdata_cfg) ? rwdata_reg : HWDATA;
assign PSEL = (state_reg==ST_APB_TRNF) | (state_reg==ST_APB_TRNF2);
assign PENABLE = (state_reg==ST_APB_TRNF2);
assign PPROT = {pprot_reg[1], 1'b0, pprot_reg[0]};
assign PSTRB = pstrb_reg[3:0];
// Generate HREADYOUT
always @(state_reg or reg_rdata_cfg or PREADY or PSLVERR or PCLKEN)
begin
case (state_reg)
ST_IDLE : HREADYOUT = 1'b1; // Idle
ST_APB_WAIT : HREADYOUT = 1'b0; // Transfer announced on AHB, but PCLKEN was low, so waiting
ST_APB_TRNF : HREADYOUT = 1'b0; // First APB transfer cycle
// Second APB transfer cycle:
// if Non-registered feedback version, and APB transfer completed without error
// Then response with ready immediately. If registered feedback version,
// wait until state_reg==ST_APB_ENDOK
ST_APB_TRNF2 : HREADYOUT = (~reg_rdata_cfg) & PREADY & (~PSLVERR) & PCLKEN;
ST_APB_ENDOK : HREADYOUT = reg_rdata_cfg; // Ending cycle for OKAY (registered response only)
ST_APB_ERR1 : HREADYOUT = 1'b0; // First cycle for Error response
ST_APB_ERR2 : HREADYOUT = 1'b1; // Second cycle for Error response
default: HREADYOUT = 1'bx; // x propagation (note :3'b111 is illegal state)
endcase
end
// From sample register or from PRDATA directly
assign HRDATA = (reg_rdata_cfg) ? rwdata_reg : PRDATA;
assign HRESP = (state_reg==ST_APB_ERR1) | (state_reg==ST_APB_ERR2);
assign APBACTIVE = (HSEL & HTRANS[1]) | (|state_reg);
`ifdef ARM_AHB_ASSERT_ON
// ------------------------------------------------------------
// Assertions
// ------------------------------------------------------------
`include "std_ovl_defines.h"
// Capture last read APB data
reg [31:0] ovl_last_read_apb_data_reg;
always @(posedge HCLK or negedge HRESETn)
begin
if (~HRESETn)
ovl_last_read_apb_data_reg <= {32{1'b0}};
else if (PREADY & PENABLE & (~PWRITE) & PSEL & PCLKEN)
ovl_last_read_apb_data_reg <= PRDATA;
end
// Capture last APB response, clear at start of APB transfer
reg ovl_last_read_apb_resp_reg;
always @(posedge HCLK or negedge HRESETn)
begin
if (~HRESETn)
ovl_last_read_apb_resp_reg <= 1'b0;
else
begin
if (PCLKEN)
begin
if (PREADY & PSEL)
ovl_last_read_apb_resp_reg <= PSLVERR & PENABLE;
else if (PSEL)
ovl_last_read_apb_resp_reg <= 1'b0;
end
end
end
// Create signal to indicate data phase
reg ovl_ahb_data_phase_reg;
wire ovl_ahb_data_phase_nxt = HSEL & HTRANS[1];
always @(posedge HCLK or negedge HRESETn)
begin
if (~HRESETn)
ovl_ahb_data_phase_reg <= 1'b0;
else if (HREADY)
ovl_ahb_data_phase_reg <= ovl_ahb_data_phase_nxt;
end
generate
if(REGISTER_RDATA!=0) begin : gen_ovl_read_data_mistmatch
// Last read APB data should be the same as HRDATA, unless there is an error response
// (Only check if using registered read data config. Otherwise HRDATA is directly connected
// to PRDATA so no need to have OVL check)
assert_implication
#(`OVL_ERROR,`OVL_ASSERT,
"Read data mismatch")
u_ovl_read_data_mistmatch
(.clk(HCLK), .reset_n(HRESETn),
.antecedent_expr(ovl_ahb_data_phase_reg & (~wr_reg) & HREADYOUT & (~HRESP)),
.consequent_expr(ovl_last_read_apb_data_reg==HRDATA)
);
end
endgenerate
// AHB response should match APB response
assert_implication
#(`OVL_ERROR,`OVL_ASSERT,
"Response mismatch")
u_ovl_resp_mistmatch
(.clk(HCLK), .reset_n(HRESETn),
.antecedent_expr(ovl_ahb_data_phase_reg & HREADYOUT),
.consequent_expr(ovl_last_read_apb_resp_reg==HRESP)
);
// APBACTIVE should be high before and during APB transfers
assert_implication
#(`OVL_ERROR,`OVL_ASSERT,
"APBACTIVE should be active when PSEL is high")
u_ovl_apbactive_1
(.clk(HCLK), .reset_n(HRESETn),
.antecedent_expr(PSEL),
.consequent_expr(APBACTIVE)
);
assert_implication
#(`OVL_ERROR,`OVL_ASSERT,
"APBACTIVE should be active when there is an active transfer (data phase)")
u_ovl_apbactive_2
(.clk(HCLK), .reset_n(HRESETn),
.antecedent_expr(~HREADYOUT),
.consequent_expr(APBACTIVE)
);
assert_implication
#(`OVL_ERROR,`OVL_ASSERT,
"APBACTIVE should be active when AHB to APB bridge is selected")
u_ovl_apbactive_3
(.clk(HCLK), .reset_n(HRESETn),
.antecedent_expr((HSEL & HTRANS[1])),
.consequent_expr(APBACTIVE)
);
// Create register to check a transfer on AHB side result in a transfer in APB side
reg ovl_transfer_started_reg;
// Set by transfer starting, clear by PSEL
wire ovl_transfer_started_nxt = (HREADY & ovl_ahb_data_phase_nxt) |
(ovl_transfer_started_reg & (~PSEL));
always @(posedge HCLK or negedge HRESETn)
begin
if (~HRESETn)
ovl_transfer_started_reg <= 1'b0;
else
ovl_transfer_started_reg <= ovl_transfer_started_nxt;
end
// Check a valid transfer must result in an APB transfer
assert_never
#(`OVL_ERROR,`OVL_ASSERT,
"APB transfer missing.")
u_ovl_apb_transfer_missing
(.clk(HCLK), .reset_n(HRESETn),
.test_expr(HREADY & ovl_ahb_data_phase_nxt & ovl_transfer_started_reg)
);
// Ensure state_reg must not be 3'b111
assert_never
#(`OVL_ERROR,`OVL_ASSERT,
"state_reg in illegal state")
u_ovl_rx_state_illegal
(.clk(HCLK), .reset_n(HRESETn),
.test_expr(state_reg==ST_ILLEGAL));
`endif
endmodule

View File

@ -0,0 +1,226 @@
//-----------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from ARM Limited.
//
// (C) COPYRIGHT 2010-2013 ARM Limited.
// ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from ARM Limited.
//
// SVN Information
//
// Checked In : $Date: 2013-04-15 17:00:07 +0100 (Mon, 15 Apr 2013) $
//
// Revision : $Revision: 244029 $
//
// Release Information : Cortex-M System Design Kit-r1p0-00rel0
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Abstract : APB slave multiplex
//-----------------------------------------------------------------------------
module cmsdk_apb_slave_mux #(
// Parameters to enable/disable ports
parameter PORT0_ENABLE = 1,
parameter PORT1_ENABLE = 1,
parameter PORT2_ENABLE = 1,
parameter PORT3_ENABLE = 1,
parameter PORT4_ENABLE = 1,
parameter PORT5_ENABLE = 1,
parameter PORT6_ENABLE = 1,
parameter PORT7_ENABLE = 1,
parameter PORT8_ENABLE = 1,
parameter PORT9_ENABLE = 1,
parameter PORT10_ENABLE = 1,
parameter PORT11_ENABLE = 1,
parameter PORT12_ENABLE = 1,
parameter PORT13_ENABLE = 1,
parameter PORT14_ENABLE = 1,
parameter PORT15_ENABLE = 1)
(
// --------------------------------------------------------------------------
// Port Definitions
// --------------------------------------------------------------------------
input wire [3:0] DECODE4BIT,
input wire PSEL,
output wire PSEL0,
input wire PREADY0,
input wire [31:0] PRDATA0,
input wire PSLVERR0,
output wire PSEL1,
input wire PREADY1,
input wire [31:0] PRDATA1,
input wire PSLVERR1,
output wire PSEL2,
input wire PREADY2,
input wire [31:0] PRDATA2,
input wire PSLVERR2,
output wire PSEL3,
input wire PREADY3,
input wire [31:0] PRDATA3,
input wire PSLVERR3,
output wire PSEL4,
input wire PREADY4,
input wire [31:0] PRDATA4,
input wire PSLVERR4,
output wire PSEL5,
input wire PREADY5,
input wire [31:0] PRDATA5,
input wire PSLVERR5,
output wire PSEL6,
input wire PREADY6,
input wire [31:0] PRDATA6,
input wire PSLVERR6,
output wire PSEL7,
input wire PREADY7,
input wire [31:0] PRDATA7,
input wire PSLVERR7,
output wire PSEL8,
input wire PREADY8,
input wire [31:0] PRDATA8,
input wire PSLVERR8,
output wire PSEL9,
input wire PREADY9,
input wire [31:0] PRDATA9,
input wire PSLVERR9,
output wire PSEL10,
input wire PREADY10,
input wire [31:0] PRDATA10,
input wire PSLVERR10,
output wire PSEL11,
input wire PREADY11,
input wire [31:0] PRDATA11,
input wire PSLVERR11,
output wire PSEL12,
input wire PREADY12,
input wire [31:0] PRDATA12,
input wire PSLVERR12,
output wire PSEL13,
input wire PREADY13,
input wire [31:0] PRDATA13,
input wire PSLVERR13,
output wire PSEL14,
input wire PREADY14,
input wire [31:0] PRDATA14,
input wire PSLVERR14,
output wire PSEL15,
input wire PREADY15,
input wire [31:0] PRDATA15,
input wire PSLVERR15,
output wire PREADY,
output wire [31:0] PRDATA,
output wire PSLVERR);
// --------------------------------------------------------------------------
// Start of main code
// --------------------------------------------------------------------------
wire [15:0] en = { (PORT15_ENABLE == 1), (PORT14_ENABLE == 1),
(PORT13_ENABLE == 1), (PORT12_ENABLE == 1),
(PORT11_ENABLE == 1), (PORT10_ENABLE == 1),
(PORT9_ENABLE == 1), (PORT8_ENABLE == 1),
(PORT7_ENABLE == 1), (PORT6_ENABLE == 1),
(PORT5_ENABLE == 1), (PORT4_ENABLE == 1),
(PORT3_ENABLE == 1), (PORT2_ENABLE == 1),
(PORT1_ENABLE == 1), (PORT0_ENABLE == 1) };
wire [15:0] dec = { (DECODE4BIT == 4'd15), (DECODE4BIT == 4'd14),
(DECODE4BIT == 4'd13), (DECODE4BIT == 4'd12),
(DECODE4BIT == 4'd11), (DECODE4BIT == 4'd10),
(DECODE4BIT == 4'd9 ), (DECODE4BIT == 4'd8 ),
(DECODE4BIT == 4'd7 ), (DECODE4BIT == 4'd6 ),
(DECODE4BIT == 4'd5 ), (DECODE4BIT == 4'd4 ),
(DECODE4BIT == 4'd3 ), (DECODE4BIT == 4'd2 ),
(DECODE4BIT == 4'd1 ), (DECODE4BIT == 4'd0 ) };
assign PSEL0 = PSEL & dec[ 0] & en[ 0];
assign PSEL1 = PSEL & dec[ 1] & en[ 1];
assign PSEL2 = PSEL & dec[ 2] & en[ 2];
assign PSEL3 = PSEL & dec[ 3] & en[ 3];
assign PSEL4 = PSEL & dec[ 4] & en[ 4];
assign PSEL5 = PSEL & dec[ 5] & en[ 5];
assign PSEL6 = PSEL & dec[ 6] & en[ 6];
assign PSEL7 = PSEL & dec[ 7] & en[ 7];
assign PSEL8 = PSEL & dec[ 8] & en[ 8];
assign PSEL9 = PSEL & dec[ 9] & en[ 9];
assign PSEL10 = PSEL & dec[10] & en[10];
assign PSEL11 = PSEL & dec[11] & en[11];
assign PSEL12 = PSEL & dec[12] & en[12];
assign PSEL13 = PSEL & dec[13] & en[13];
assign PSEL14 = PSEL & dec[14] & en[14];
assign PSEL15 = PSEL & dec[15] & en[15];
assign PREADY = ~PSEL |
( dec[ 0] & (PREADY0 | ~en[ 0]) ) |
( dec[ 1] & (PREADY1 | ~en[ 1]) ) |
( dec[ 2] & (PREADY2 | ~en[ 2]) ) |
( dec[ 3] & (PREADY3 | ~en[ 3]) ) |
( dec[ 4] & (PREADY4 | ~en[ 4]) ) |
( dec[ 5] & (PREADY5 | ~en[ 5]) ) |
( dec[ 6] & (PREADY6 | ~en[ 6]) ) |
( dec[ 7] & (PREADY7 | ~en[ 7]) ) |
( dec[ 8] & (PREADY8 | ~en[ 8]) ) |
( dec[ 9] & (PREADY9 | ~en[ 9]) ) |
( dec[10] & (PREADY10 | ~en[10]) ) |
( dec[11] & (PREADY11 | ~en[11]) ) |
( dec[12] & (PREADY12 | ~en[12]) ) |
( dec[13] & (PREADY13 | ~en[13]) ) |
( dec[14] & (PREADY14 | ~en[14]) ) |
( dec[15] & (PREADY15 | ~en[15]) );
assign PSLVERR = ( PSEL0 & PSLVERR0 ) |
( PSEL1 & PSLVERR1 ) |
( PSEL2 & PSLVERR2 ) |
( PSEL3 & PSLVERR3 ) |
( PSEL4 & PSLVERR4 ) |
( PSEL5 & PSLVERR5 ) |
( PSEL6 & PSLVERR6 ) |
( PSEL7 & PSLVERR7 ) |
( PSEL8 & PSLVERR8 ) |
( PSEL9 & PSLVERR9 ) |
( PSEL10 & PSLVERR10 ) |
( PSEL11 & PSLVERR11 ) |
( PSEL12 & PSLVERR12 ) |
( PSEL13 & PSLVERR13 ) |
( PSEL14 & PSLVERR14 ) |
( PSEL15 & PSLVERR15 );
assign PRDATA = ( {32{PSEL0 }} & PRDATA0 ) |
( {32{PSEL1 }} & PRDATA1 ) |
( {32{PSEL2 }} & PRDATA2 ) |
( {32{PSEL3 }} & PRDATA3 ) |
( {32{PSEL4 }} & PRDATA4 ) |
( {32{PSEL5 }} & PRDATA5 ) |
( {32{PSEL6 }} & PRDATA6 ) |
( {32{PSEL7 }} & PRDATA7 ) |
( {32{PSEL8 }} & PRDATA8 ) |
( {32{PSEL9 }} & PRDATA9 ) |
( {32{PSEL10}} & PRDATA10 ) |
( {32{PSEL11}} & PRDATA11 ) |
( {32{PSEL12}} & PRDATA12 ) |
( {32{PSEL13}} & PRDATA13 ) |
( {32{PSEL14}} & PRDATA14 ) |
( {32{PSEL15}} & PRDATA15 );
endmodule

91
hardware/constraint.xdc Normal file
View File

@ -0,0 +1,91 @@
############## NET - IOSTANDARD ###################
set_property CFGBVS VCCO [current_design]
set_property CONFIG_VOLTAGE 3.3 [current_design]
#############SPI Configurate Setting###############
set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]
set_property CONFIG_MODE SPIx4 [current_design]
set_property BITSTREAM.CONFIG.CONFIGRATE 50 [current_design]
############## Clock ##############################
create_clock -period 20.000 [get_ports CLK50M]
set_property IOSTANDARD LVCMOS33 [get_ports CLK50M]
set_property PACKAGE_PIN P15 [get_ports CLK50M]
############## LEDs ###############################
set_property IOSTANDARD LVCMOS33 [get_ports {ledNumOut[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ledNumOut[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ledNumOut[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {ledNumOut[0]}]
set_property PACKAGE_PIN H16 [get_ports {ledNumOut[3]}]
set_property PACKAGE_PIN G16 [get_ports {ledNumOut[2]}]
set_property PACKAGE_PIN K15 [get_ports {ledNumOut[1]}]
set_property PACKAGE_PIN J15 [get_ports {ledNumOut[0]}]
############## UART ################################
set_property IOSTANDARD LVCMOS33 [get_ports TXD]
set_property IOSTANDARD LVCMOS33 [get_ports RXD]
set_property PACKAGE_PIN D11 [get_ports TXD]
set_property PACKAGE_PIN B16 [get_ports RXD]
############## Buttons #############################
set_property IOSTANDARD LVCMOS33 [get_ports RSTn]
set_property PACKAGE_PIN M15 [get_ports RSTn]
#############HDMI_O####################################
set_property IOSTANDARD LVTTL [get_ports tmds_clk_n]
set_property PACKAGE_PIN A20 [get_ports tmds_clk_n]
set_property PACKAGE_PIN B20 [get_ports tmds_clk_p]
set_property IOSTANDARD LVTTL [get_ports tmds_clk_p]
set_property IOSTANDARD LVTTL [get_ports {tmds_data_n[0]}]
set_property PACKAGE_PIN A17 [get_ports {tmds_data_n[0]}]
set_property PACKAGE_PIN A16 [get_ports {tmds_data_p[0]}]
set_property IOSTANDARD LVTTL [get_ports {tmds_data_p[0]}]
set_property IOSTANDARD LVTTL [get_ports {tmds_data_n[1]}]
set_property PACKAGE_PIN A13 [get_ports {tmds_data_n[1]}]
set_property PACKAGE_PIN B13 [get_ports {tmds_data_p[1]}]
set_property IOSTANDARD LVTTL [get_ports {tmds_data_p[1]}]
set_property IOSTANDARD LVTTL [get_ports {tmds_data_n[2]}]
set_property PACKAGE_PIN A12 [get_ports {tmds_data_n[2]}]
set_property PACKAGE_PIN A11 [get_ports {tmds_data_p[2]}]
set_property IOSTANDARD LVTTL [get_ports {tmds_data_p[2]}]
############## CMOS define############################
set_property PACKAGE_PIN C22 [get_ports cmos_scl]
set_property PACKAGE_PIN D21 [get_ports cmos_sda]
set_property PACKAGE_PIN B22 [get_ports cmos_pclk]
set_property PACKAGE_PIN D18 [get_ports cmos_href]
set_property PACKAGE_PIN B21 [get_ports cmos_vsync]
set_property PACKAGE_PIN B19 [get_ports {cmos_db[7]}]
set_property PACKAGE_PIN C19 [get_ports {cmos_db[6]}]
set_property PACKAGE_PIN C16 [get_ports {cmos_db[5]}]
set_property PACKAGE_PIN D16 [get_ports {cmos_db[4]}]
set_property PACKAGE_PIN C20 [get_ports {cmos_db[3]}]
set_property PACKAGE_PIN D20 [get_ports {cmos_db[2]}]
set_property PACKAGE_PIN C15 [get_ports {cmos_db[1]}]
set_property PACKAGE_PIN C17 [get_ports {cmos_db[0]}]
set_property PACKAGE_PIN C18 [get_ports cmos_xclk]
set_property IOSTANDARD LVCMOS33 [get_ports cmos_sda]
set_property IOSTANDARD LVCMOS33 [get_ports cmos_scl]
set_property IOSTANDARD LVCMOS33 [get_ports {cmos_db[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {cmos_db[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {cmos_db[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {cmos_db[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {cmos_db[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {cmos_db[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {cmos_db[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {cmos_db[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports cmos_pclk]
set_property IOSTANDARD LVCMOS33 [get_ports cmos_href]
set_property IOSTANDARD LVCMOS33 [get_ports cmos_vsync]
set_property IOSTANDARD LVCMOS33 [get_ports cmos_xclk]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets cmos_pclk_IBUF]

File diff suppressed because it is too large Load Diff

71
hardware/ddr3.ucf Normal file
View File

@ -0,0 +1,71 @@
NET "ddr3_dq[0]" LOC = "H2" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[1]" LOC = "K2" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[2]" LOC = "H3" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[3]" LOC = "H6" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[4]" LOC = "H5" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[5]" LOC = "K6" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[6]" LOC = "H4" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[7]" LOC = "J3" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[8]" LOC = "M8" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[9]" LOC = "L8" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[10]" LOC = "L6" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[11]" LOC = "J8" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[12]" LOC = "K4" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[13]" LOC = "K8" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[14]" LOC = "L4" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[15]" LOC = "J7" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[16]" LOC = "L1" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[17]" LOC = "P3" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[18]" LOC = "K1" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[19]" LOC = "N4" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[20]" LOC = "N1" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[21]" LOC = "P1" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[22]" LOC = "M3" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[23]" LOC = "N3" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[24]" LOC = "R4" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[25]" LOC = "R6" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[26]" LOC = "P7" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[27]" LOC = "N5" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[28]" LOC = "R7" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[29]" LOC = "N7" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[30]" LOC = "P8" | IOSTANDARD = SSTL15 ;
NET "ddr3_dq[31]" LOC = "R5" | IOSTANDARD = SSTL15 ;
NET "ddr3_dm[0]" LOC = "K3" | IOSTANDARD = SSTL15 ;
NET "ddr3_dm[1]" LOC = "L7" | IOSTANDARD = SSTL15 ;
NET "ddr3_dm[2]" LOC = "M4" | IOSTANDARD = SSTL15 ;
NET "ddr3_dm[3]" LOC = "M5" | IOSTANDARD = SSTL15 ;
NET "ddr3_dqs_p[0]" LOC = "J2" | IOSTANDARD = DIFF_SSTL15 ;
NET "ddr3_dqs_n[0]" LOC = "J1" | IOSTANDARD = DIFF_SSTL15 ;
NET "ddr3_dqs_p[1]" LOC = "L5" | IOSTANDARD = DIFF_SSTL15 ;
NET "ddr3_dqs_n[1]" LOC = "K5" | IOSTANDARD = DIFF_SSTL15 ;
NET "ddr3_dqs_p[2]" LOC = "M2" | IOSTANDARD = DIFF_SSTL15 ;
NET "ddr3_dqs_n[2]" LOC = "M1" | IOSTANDARD = DIFF_SSTL15 ;
NET "ddr3_dqs_p[3]" LOC = "P6" | IOSTANDARD = DIFF_SSTL15 ;
NET "ddr3_dqs_n[3]" LOC = "N6" | IOSTANDARD = DIFF_SSTL15 ;
NET "ddr3_addr[14]" LOC = "Y4" | IOSTANDARD = SSTL15 ;
NET "ddr3_addr[13]" LOC = "U4" | IOSTANDARD = SSTL15 ;
NET "ddr3_addr[12]" LOC = "U1" | IOSTANDARD = SSTL15 ;
NET "ddr3_addr[11]" LOC = "W2" | IOSTANDARD = SSTL15 ;
NET "ddr3_addr[10]" LOC = "Y5" | IOSTANDARD = SSTL15 ;
NET "ddr3_addr[9]" LOC = "Y6" | IOSTANDARD = SSTL15 ;
NET "ddr3_addr[8]" LOC = "W4" | IOSTANDARD = SSTL15 ;
NET "ddr3_addr[7]" LOC = "U5" | IOSTANDARD = SSTL15 ;
NET "ddr3_addr[6]" LOC = "W1" | IOSTANDARD = SSTL15 ;
NET "ddr3_addr[5]" LOC = "T6" | IOSTANDARD = SSTL15 ;
NET "ddr3_addr[4]" LOC = "W5" | IOSTANDARD = SSTL15 ;
NET "ddr3_addr[3]" LOC = "T7" | IOSTANDARD = SSTL15 ;
NET "ddr3_addr[2]" LOC = "T5" | IOSTANDARD = SSTL15 ;
NET "ddr3_addr[1]" LOC = "U3" | IOSTANDARD = SSTL15 ;
NET "ddr3_addr[0]" LOC = "Y3" | IOSTANDARD = SSTL15 ;
NET "ddr3_ba[2]" LOC = "W3" | IOSTANDARD = SSTL15 ;
NET "ddr3_ba[1]" LOC = "U2" | IOSTANDARD = SSTL15 ;
NET "ddr3_ba[0]" LOC = "Y1" | IOSTANDARD = SSTL15 ;
NET "ddr3_ck_p[0]" LOC = "T3" | IOSTANDARD = DIFF_SSTL15 ;
NET "ddr3_ck_n[0]" LOC = "T2" | IOSTANDARD = DIFF_SSTL15 ;
NET "ddr3_ras_n" LOC = "V7" | IOSTANDARD = SSTL15 ;
NET "ddr3_cas_n" LOC = "T8" | IOSTANDARD = SSTL15 ;
NET "ddr3_we_n" LOC = "U8" | IOSTANDARD = SSTL15 ;
NET "ddr3_reset_n" LOC = "AA1" | IOSTANDARD = LVCMOS15 ;
NET "ddr3_cke[0]" LOC = "V4" | IOSTANDARD = SSTL15 ;
NET "ddr3_odt[0]" LOC = "V6" | IOSTANDARD = SSTL15 ;
NET "ddr3_cs_n[0]" LOC = "V1" | IOSTANDARD = SSTL15 ;

59906
hardware/facefinder.coe Normal file

File diff suppressed because it is too large Load Diff

1771
hardware/minSOC.v Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,821 @@
/* *****************************************************************
* This code is released under the MIT License.
* Copyright (c) 2020 Xuanzhi LIU, Qiao HU, Zongwu HE
*
* For latest version of this code or to issue a problem,
* please visit: <https://github.com/WalkerLau/DetectHumanFaces>
*
* Note: the above information must be kept whenever or wherever the codes are used.
*
* *****************************************************************/
module accelerator #(
parameter RCS_ADDR =32'h0,
parameter CONF_ADDR =32'h0,
parameter RETURN_ADDR =32'h0
)
(
// Reset, Clock
input ARESETN,
input ACLK,
// Master Write Address
output [0:0] M_AXI_AWID,
output [31:0] M_AXI_AWADDR,
output [7:0] M_AXI_AWLEN, // Burst Length: 0-255
output [2:0] M_AXI_AWSIZE, // Burst Size: Fixed 2'b011
output [1:0] M_AXI_AWBURST, // Burst Type: Fixed 2'b01(Incremental Burst)
output M_AXI_AWLOCK, // Lock: Fixed 2'b00
output [3:0] M_AXI_AWCACHE, // Cache: Fiex 2'b0011
output [2:0] M_AXI_AWPROT, // Protect: Fixed 2'b000
output [3:0] M_AXI_AWQOS, // QoS: Fixed 2'b0000
output [0:0] M_AXI_AWUSER, // User: Fixed 1'b0
output M_AXI_AWVALID,
input M_AXI_AWREADY,
// Master Write Data
output [31:0] M_AXI_WDATA,
output [3:0] M_AXI_WSTRB,
output M_AXI_WLAST,
output [0:0] M_AXI_WUSER,
output M_AXI_WVALID,
input M_AXI_WREADY,
// Master Write Response
input [0:0] M_AXI_BID,
input [1:0] M_AXI_BRESP,
input [0:0] M_AXI_BUSER,
input M_AXI_BVALID,
output M_AXI_BREADY,
// Master Read Address
output [0:0] M_AXI_ARID,
output [31:0] M_AXI_ARADDR,
output [7:0] M_AXI_ARLEN,
output [2:0] M_AXI_ARSIZE,
output [1:0] M_AXI_ARBURST,
output [1:0] M_AXI_ARLOCK,
output [3:0] M_AXI_ARCACHE,
output [2:0] M_AXI_ARPROT,
output [3:0] M_AXI_ARQOS,
output [0:0] M_AXI_ARUSER,
output M_AXI_ARVALID,
input M_AXI_ARREADY,
// Master Read Data
input [0:0] M_AXI_RID,
input [31:0] M_AXI_RDATA,
input [1:0] M_AXI_RRESP,
input M_AXI_RLAST,
input [0:0] M_AXI_RUSER,
input M_AXI_RVALID,
output M_AXI_RREADY,
input write_addr_index,
input ignite_acc,
output ignite_ready,
output ACC_IRQ,
input ACC_IRQ_READY,
// LocalMem
input [31:0] MEM_RDATA,
output reg[15:0] MEM_ADRS
);
// AXI write channel fixed ports
assign M_AXI_AWID = 1'b0;
assign M_AXI_AWADDR[31:0] = reg_wr_adrs[31:0];
assign M_AXI_AWLEN[7:0] = reg_w_len[7:0];
assign M_AXI_AWSIZE[2:0] = 2'b010;
assign M_AXI_AWBURST[1:0] = 2'b01;
assign M_AXI_AWLOCK = 1'b0;
assign M_AXI_AWCACHE[3:0] = 4'b0011;
assign M_AXI_AWPROT[2:0] = 3'b000;
assign M_AXI_AWQOS[3:0] = 4'b0000;
assign M_AXI_AWUSER[0] = 1'b0;
assign M_AXI_AWVALID = reg_awvalid;
assign M_AXI_WDATA[31:0] = wr_data;
assign M_AXI_WSTRB[3:0] = (reg_wvalid)?4'hF:4'h0;
assign M_AXI_WLAST = (reg_w_len[7:0] == 8'd0)?1'b1:1'b0;
assign M_AXI_WUSER = 1'b0;
assign M_AXI_WVALID = reg_wvalid;
assign M_AXI_BREADY = M_AXI_BVALID;
//AXI read channel fixed ports
assign M_AXI_ARID = 1'b0;
assign M_AXI_ARADDR[31:0] = reg_rd_adrs[31:0];
assign M_AXI_ARLEN[7:0] = reg_r_len[7:0];
assign M_AXI_ARSIZE[2:0] = 3'b010;
assign M_AXI_ARBURST[1:0] = 2'b01;
assign M_AXI_ARLOCK = 1'b0;
assign M_AXI_ARCACHE[3:0] = 4'b0011;
assign M_AXI_ARPROT[2:0] = 3'b000;
assign M_AXI_ARQOS[3:0] = 4'b0000;
assign M_AXI_ARUSER[0] = 1'b0;
assign M_AXI_ARVALID = reg_arvalid;
assign M_AXI_RREADY = M_AXI_RVALID;
localparam AM_WAIT = 8'd0;
localparam S_RA_START = 8'd1;
localparam S_RD_WAIT = 8'd2;
localparam S_RD_PROC = 8'd3;
localparam S_RD_DONE = 8'd4;
localparam S_WA_WAIT = 8'd5;
localparam S_WA_START = 8'd6;
localparam S_WD_WAIT = 8'd7;
localparam S_WD_PROC = 8'd8;
localparam S_WR_WAIT = 8'd9;
localparam S_WR_DONE = 8'd10;
//
localparam M_NONE = 2'b00;
localparam M_READ = 2'b01;
localparam M_WRITE = 2'b10;
// Access Mode control
reg [1:0] AccessMode;
always @ (posedge ACLK or negedge ARESETN)begin
if(!ARESETN)begin
AccessMode <= M_NONE;
end
else begin
if(am_r_valid)begin
AccessMode <= M_READ;
end
else if(am_w_valid)begin
AccessMode <= M_WRITE;
end
else begin
AccessMode <= M_NONE;
end
end
end
// ALL-IN-ONE AXI ACCESS STATE MACHINE
reg [7:0] am_state;
reg [31:0] reg_rd_adrs;
reg reg_arvalid;
reg [7:0] reg_r_len;
reg am_r_ready;
reg [31:0] reg_wr_adrs;
reg reg_awvalid, reg_wvalid;
reg [7:0] reg_w_len;
reg am_w_ready;
reg [1:0] reg_wr_status;
always @(posedge ACLK or negedge ARESETN) begin
if(!ARESETN) begin
am_state <= AM_WAIT;
reg_rd_adrs[31:0] <= 32'd0;
reg_arvalid <= 1'b0;
reg_wr_adrs[31:0] <= 32'd0;
reg_awvalid <= 1'b0;
reg_wvalid <= 1'b0;
reg_w_len[7:0] <= 8'd0;
reg_wr_status[1:0] <= 2'd0;
am_r_ready <= 1'b0;
am_w_ready <= 1'b0;
end else begin
case(am_state)
AM_WAIT: begin
if(AccessMode == M_WRITE)begin
am_state <= S_WA_START;
reg_wr_adrs[31:0] <= WR_ADRS[31:0];
end
else if(AccessMode == M_READ)begin
am_state <= S_RA_START;
reg_rd_adrs[31:0] <= RD_ADRS[31:0];
reg_r_len[7:0] <= RD_LEN - 8'd1; // AXI Burst_Length = AxLEN[7:0] + 1
end else begin
reg_arvalid <= 1'b0;
reg_awvalid <= 1'b0;
reg_wvalid <= 1'b0;
reg_w_len[7:0] <= 8'd0;
reg_wr_status[1:0] <= 2'd0;
am_r_ready <= 1'b0;
am_w_ready <= 1'b0;
end
end
S_RA_START: begin // this is an important state, cannot be removed!
reg_arvalid <= 1'b1;
am_r_ready <= 1'b1;
am_state <= S_RD_WAIT;
end
S_RD_WAIT: begin
if(M_AXI_ARREADY) begin
am_state <= S_RD_PROC;
reg_arvalid <= 1'b0;
am_r_ready <= 1'b0;
end
end
S_RD_PROC: begin
if(M_AXI_RVALID) begin
if(M_AXI_RLAST) begin
am_state <= S_RD_DONE;
end else begin
reg_r_len[7:0] <= reg_r_len[7:0] -8'd1;
end
end
end
S_RD_DONE: begin
am_state <= AM_WAIT;
end
S_WA_START: begin
am_state <= S_WD_WAIT;
reg_awvalid <= 1'b1;
reg_w_len[7:0] <= WR_LEN - 8'd1; // AXI Burst_Length = AxLEN[7:0] + 1, this line shouldn't be placed in S_WR_IDLE
am_w_ready <= 1'b1;
end
S_WD_WAIT: begin
if(M_AXI_AWREADY) begin
am_state <= S_WD_PROC;
reg_awvalid <= 1'b0;
reg_wvalid <= 1'b1;
am_w_ready <= 1'b0;
end
end
S_WD_PROC: begin
if(M_AXI_WREADY) begin
if(M_AXI_WLAST) begin
am_state <= S_WR_WAIT;
reg_wvalid <= 1'b0;
end else begin
reg_w_len[7:0] <= reg_w_len[7:0] - 8'd1;
end
end
end
S_WR_WAIT: begin
if(M_AXI_BVALID) begin
reg_wr_status[1:0] <= M_AXI_BRESP[1:0];
am_state <= S_WR_DONE;
end
end
S_WR_DONE: begin
am_state <= AM_WAIT;
end
default: begin
am_state <= AM_WAIT;
end
endcase
end
end
//////////////////////////////////////////////////////////////////////////////////////////////////
parameter NROWS =480;
parameter NCOLS =640;
parameter TDEPTH =6;
parameter NTREES =468;
parameter OFFSET =128;
parameter PIC_ADDR_1 =32'h2bc00000;
parameter PIC_ADDR_2 =32'h2be00000;
//parameter CASCADE_ADDR =32'h28000000;
localparam IDLE = 6'd0;
localparam RCS_S1 = 6'd1;
localparam RCS_S2 = 6'd2;
localparam LOAD_RCS = 6'd3;
localparam CHECK_BOUNDRY = 6'd4;
localparam WRITE_RETURN1_S1 = 6'd5;
localparam WRITE_RETURN1_S2 = 6'd6;
localparam FORLOOP1 = 6'd7;
localparam F1_IDLE = 6'd8;
localparam FORLOOP2 = 6'd9;
localparam TCODE_S1 = 6'd10;
localparam TCODE_S2 = 6'd11;
localparam TCODE_S3 = 6'd12;
localparam LOAD_TCODE = 6'd13;
localparam CAL_REMAINDER = 6'd14;
localparam READ_PIX1_S1 = 6'd15;
localparam READ_PIX1_S2 = 6'd16;
localparam LOAD_PIX1 = 6'd17;
localparam READ_PIX2_S1 = 6'd18;
localparam READ_PIX2_S2 = 6'd19;
localparam LOAD_PIX2 = 6'd20;
localparam F1_PIX_COMP = 6'd21;
localparam F1_IDX_ADD = 6'd22;
localparam LUT_S1 = 6'd23;
localparam LUT_S2 = 6'd24;
localparam LUT_S3 = 6'd25;
localparam F1_CONF_ADD = 6'd26;
localparam THR_S1 = 6'd27;
localparam THR_S2 = 6'd28;
localparam THR_S3 = 6'd29;
localparam F1_CONF_COMP = 6'd30;
localparam WRITE_RETURN2_S1 = 6'd31;
localparam WRITE_RETURN2_S2 = 6'd32;
localparam CONF_SUB = 6'd33;
localparam WRITE_CONF_S1 = 6'd34;
localparam WRITE_CONF_S2 = 6'd35;
localparam WRITE_RETURN3_S1 = 6'd36;
localparam WRITE_RETURN3_S2 = 6'd37;
localparam RETURN_VAL1 = 6'd38;
localparam RETURN_VAL2 = 6'd39;
localparam RETURN_VAL3 = 6'd40;
localparam RETURN_VAL4 = 6'd41;
localparam RETURN_VAL5 = 6'd42;
localparam RETURN_VAL6 = 6'd43;
reg [5:0] state;
reg signed [31:0] r_new;
reg signed [31:0] c_new;
reg signed [31:0] s_new;
reg [15:0] ptree_addr;
reg signed [31:0] pixels_addr;
reg [8:0] counter_1;
reg [2:0] counter_2;
reg [31:0] idx;
reg [15:0] tcodes_addr;
reg [15:0] lut_addr;
reg [15:0] thr_addr;
reg [7:0] pixels_1;
reg [7:0] pixels_2;
reg pixels_flag;
reg[31:0] o;
reg [31:0] RD_ADRS;
reg [7:0] RD_LEN;
reg am_r_valid;
reg [31:0] WR_ADRS;
reg [7:0] WR_LEN;
reg am_w_valid;
reg [95:0] rcs_reg;
reg [31:0] tcode_reg;
reg [31:0] wr_data;
reg signed [7:0] tcodes_1;
reg signed [7:0] tcodes_2;
reg signed [7:0] tcodes_3;
reg signed [7:0] tcodes_4;
reg [31:0] lut;
reg [31:0] thr;
reg [31:0] thr_last;
reg signed [31:0] remainder_1;
reg signed [31:0] remainder_2;
reg [31:0] pixels_1_1;
reg [31:0] pixels_2_2;
reg ignite_ready;
reg ACC_IRQ;
reg result;
always@(posedge ACLK or negedge ARESETN)
begin
if(ARESETN == 1'b0)
begin
result <= 1'd0;
state <= IDLE;
RD_ADRS <= 32'd0;
RD_LEN <= 8'd0;
WR_ADRS <= 32'd0;
WR_LEN <= 8'd0;
am_r_valid <= 1'b0;
am_w_valid <= 1'b0;
ignite_ready <= 1'b0;
ACC_IRQ <= 1'b0;
rcs_reg <= 96'd0;
tcode_reg <= 32'd0;
tcodes_1 <= 8'd0;
tcodes_2 <= 8'd0;
tcodes_3 <= 8'd0;
tcodes_4 <= 8'd0;
lut <= 32'd0;
thr <= 32'd0;
thr_last <= 32'd0;
MEM_ADRS <= 0;
end
else
begin
case(state)
IDLE: begin
if(ignite_acc)begin
state <= RCS_S1;
end
ACC_IRQ <= 1'b0;
ptree_addr <= 0;
//ptree_addr <= CASCADE_ADDR + 16; //cascade是参数文件首地址
o <= 0;
counter_1 <= 0;
counter_2 <= 0;
if(write_addr_index == 1'b0)begin
pixels_addr <= PIC_ADDR_1;
end
else if(write_addr_index == 1'b1)begin
pixels_addr <= PIC_ADDR_2;
end
end
RCS_S1:
begin
if(am_r_ready == 1'b1)begin
state <= RCS_S2;
am_r_valid <= 1'b0;
end
else if(am_state == AM_WAIT)begin
RD_ADRS <= RCS_ADDR; //RCS的地址
RD_LEN <= 8'd3;
am_r_valid <= 1'b1;
end
end
RCS_S2:
begin
if(am_state == S_RD_DONE)begin
state <= LOAD_RCS;
end
else if(M_AXI_RVALID && M_AXI_RREADY)begin
rcs_reg = {rcs_reg[31:0], rcs_reg[95:32]};
rcs_reg[95: 64] = M_AXI_RDATA;
end
end
LOAD_RCS:
begin
ignite_ready <= 1'b1; // ignite_ready should stay high for at least 4 cycles
r_new <= rcs_reg[31:0] * 256;
c_new <= rcs_reg[63:32] * 256;
s_new <= rcs_reg[95:64];
state <= CHECK_BOUNDRY;
end
CHECK_BOUNDRY:
begin
if( ((r_new+(s_new*128))/256)>=NROWS || ((r_new-(s_new*128))/256)<0 || ((c_new+(s_new*128))/256)>=NCOLS || ((c_new-(s_new*128))/256)<0 )
begin
result <= 0;
state <= WRITE_RETURN1_S1;
end
else
state <= FORLOOP1;
end
WRITE_RETURN1_S1:
begin
if(am_w_ready == 1'b1)begin
state <= WRITE_RETURN1_S2;
am_w_valid <= 1'b0;
end
else if(am_state == AM_WAIT)begin
WR_ADRS <= RETURN_ADDR;
WR_LEN <= 8'd1;
wr_data <= result;
am_w_valid <= 1'b1;
end
end
WRITE_RETURN1_S2:
begin
if(am_state == S_WR_DONE)begin
state <= RETURN_VAL1;
end
end
FORLOOP1:
begin
if(counter_1 < NTREES)
begin
state <= F1_IDLE;
counter_1 <= counter_1 + 1;
end
else
begin
thr_last <= thr;
sub_start <= 1;
state <= CONF_SUB;
counter_1 <= 0;
end
end
// INIT_PTREE:
// begin
// if (counter_1 == 235) begin
// ptree_addr <= 0;
// state <= F1_IDLE;
// end else begin
// state <= F1_IDLE;
// end
// end
F1_IDLE:
begin
tcodes_addr <= ptree_addr ;
lut_addr <= ptree_addr + 63;
thr_addr <= ptree_addr + 127;
idx <= 1;
state <= FORLOOP2;
end
FORLOOP2:
begin
if(counter_2 < TDEPTH)
begin
state <= TCODE_S1;
counter_2 <= counter_2 + 1;
end
else
begin
state <= LUT_S1;
counter_2 <= 0;
end
end
// ADDR_SEL:
// begin
// if(counter_1 <=234)
// begin
// OR_reg <= 32'h80000000;
// state <= TCODE_S1;
// end
// else
// begin
// OR_reg <= 32'h00000000;
// state <= TCODE_S1;
// end
// end
TCODE_S1:
begin
state <= TCODE_S2;
MEM_ADRS <= tcodes_addr + idx[15:0] - 1;
end
TCODE_S2:begin // wait for MEM_RDATA to be stable
state <= TCODE_S3;
end
TCODE_S3:
begin
tcode_reg[31: 0] <= MEM_RDATA;
state <= LOAD_TCODE;
end
LOAD_TCODE:
begin
tcodes_1 <= tcode_reg[31:24];
tcodes_2 <= tcode_reg[23:16];
tcodes_3 <= tcode_reg[15:8];
tcodes_4 <= tcode_reg[7:0];
// tcodes_1 <= tcode_reg[7:0];
// tcodes_2 <= tcode_reg[15:8];
// tcodes_3 <= tcode_reg[23:16];
// tcodes_4 <= tcode_reg[31:24];
state <= CAL_REMAINDER;
end
CAL_REMAINDER:
begin
remainder_1 <= (((r_new + tcodes_1*s_new) >>> 8) * NCOLS + (c_new + tcodes_2*s_new)/256)*2 % 4;
remainder_2 <= (((r_new + tcodes_3*s_new) >>> 8) * NCOLS + (c_new + tcodes_4*s_new)/256)*2 % 4;
state <= READ_PIX1_S1;
end
READ_PIX1_S1:
begin
if(am_r_ready == 1'b1)begin
state <= READ_PIX1_S2;
am_r_valid <= 1'b0;
end
else if(am_state == AM_WAIT)begin
RD_ADRS <= pixels_addr + (((r_new + tcodes_1*s_new) >>> 8) * NCOLS + (c_new + tcodes_2*s_new)/256)*2 - remainder_1;
RD_LEN <= 8'd1;
am_r_valid <= 1'b1;
end
end
READ_PIX1_S2:
begin
if(am_state == S_RD_DONE)begin
state <= LOAD_PIX1;
end
else if(M_AXI_RVALID && M_AXI_RREADY)begin
pixels_1_1[31:0] <= M_AXI_RDATA;
end
end
LOAD_PIX1: // convert RGB565 to Gray
begin
case (remainder_1)
32'd0: begin pixels_1 <= ((pixels_1_1[15:11]*76) + (pixels_1_1[10: 5]*150) + (pixels_1_1[ 4: 0]*30)) >> 8; state <= READ_PIX2_S1; end
32'd2: begin pixels_1 <= ((pixels_1_1[31:27]*76) + (pixels_1_1[26:21]*150) + (pixels_1_1[20:16]*30)) >> 8; state <= READ_PIX2_S1; end
default: state <= IDLE;
endcase
end
READ_PIX2_S1:
begin
if(am_r_ready == 1'b1)begin
state <= READ_PIX2_S2;
am_r_valid <= 1'b0;
end
else if(am_state == AM_WAIT)begin
RD_ADRS <= pixels_addr + (((r_new + tcodes_3*s_new) >>> 8) * NCOLS + (c_new + tcodes_4*s_new)/256)*2 - remainder_2;
RD_LEN <= 8'd1;
am_r_valid <= 1'b1;
end
end
READ_PIX2_S2:
begin
if(am_state == S_RD_DONE)begin
state <= LOAD_PIX2;
end
else if(M_AXI_RVALID && M_AXI_RREADY)begin
pixels_2_2[31:0] <= M_AXI_RDATA;
end
end
LOAD_PIX2: // convert RGB565 to Gray
begin
case (remainder_2)
32'd0: begin pixels_2 <= ((pixels_2_2[15:11]*76) + (pixels_2_2[10: 5]*150) + (pixels_2_2[ 4: 0]*30)) >> 8; state <= F1_PIX_COMP; end
32'd2: begin pixels_2 <= ((pixels_2_2[31:27]*76) + (pixels_2_2[26:21]*150) + (pixels_2_2[20:16]*30)) >> 8; state <= F1_PIX_COMP; end
default: state <= IDLE;
endcase
end
F1_PIX_COMP:
begin
if (pixels_1<=pixels_2) begin
pixels_flag <= 1;
state <= F1_IDX_ADD;
end else begin
pixels_flag <= 0;
state <= F1_IDX_ADD;
end
end
F1_IDX_ADD:
begin
idx <= idx*2 + pixels_flag;
state <= FORLOOP2;
end
LUT_S1:
begin
state <= LUT_S2;
MEM_ADRS <= lut_addr + idx[15:0] - 64;
end
LUT_S2:begin // wait for MEM_RDATA to be stable
state <= LUT_S3;
end
LUT_S3:
begin
lut[31: 0] <= {MEM_RDATA[7:0],MEM_RDATA[15:8],MEM_RDATA[23:16],MEM_RDATA[31:24]};
add_start <= 1;
state <= F1_CONF_ADD;
end
F1_CONF_ADD:
begin
if (add_result_valid) begin
o <= add_result_wire;
state <= THR_S1;
add_start <= 0;
end
end
THR_S1:
begin
state <= THR_S2;
MEM_ADRS <= thr_addr;
end
THR_S2:// wait for MEM_RDATA to be stable
begin
state <= THR_S3;
end
THR_S3:
begin
thr[31: 0] <= {MEM_RDATA[7:0],MEM_RDATA[15:8],MEM_RDATA[23:16],MEM_RDATA[31:24]};
comp_start <= 1;
state <= F1_CONF_COMP;
end
F1_CONF_COMP:
begin
if(comp_result_valid)
begin
if (comp_result) begin
result <= 0;
state <= WRITE_RETURN2_S1;
comp_start <= 0;
end else begin
ptree_addr <= ptree_addr + OFFSET;
comp_start <= 0;
state <= FORLOOP1;
end
end
end
WRITE_RETURN2_S1:
begin
if(am_w_ready == 1'b1)begin
state <= WRITE_RETURN2_S2;
am_w_valid <= 1'b0;
end
else if(am_state == AM_WAIT)begin
WR_ADRS <= RETURN_ADDR;
WR_LEN <= 8'd1;
wr_data <= result;
am_w_valid <= 1'b1;
end
end
WRITE_RETURN2_S2:
begin
if(am_state == S_WR_DONE)begin
state <= RETURN_VAL1;
end
end
CONF_SUB:
begin
if (sub_result_valid) begin
o <= sub_result;
result <= 1;
state <= WRITE_CONF_S1;
sub_start <= 0;
end
end
WRITE_CONF_S1:
begin
if(am_w_ready == 1'b1)begin
state <= WRITE_CONF_S2;
am_w_valid <= 1'b0;
end
else if(am_state == AM_WAIT)begin
WR_ADRS <= CONF_ADDR;
WR_LEN <= 8'd1;
wr_data <= o;
am_w_valid <= 1'b1;
end
end
WRITE_CONF_S2:
begin
if(am_state == S_WR_DONE)begin
state <= WRITE_RETURN3_S1;
end
end
WRITE_RETURN3_S1:
begin
if(am_w_ready == 1'b1)begin
state <= WRITE_RETURN3_S2;
am_w_valid <= 1'b0;
end
else if(am_state == AM_WAIT)begin
WR_ADRS <= RETURN_ADDR;
WR_LEN <= 8'd1;
wr_data <= result;
am_w_valid <= 1'b1;
end
end
WRITE_RETURN3_S2:
begin
if(am_state == S_WR_DONE)begin
state <= RETURN_VAL1;
end
end
RETURN_VAL1: begin
state <= RETURN_VAL2;
ACC_IRQ <= 1'b1;
ignite_ready <= 1'b0; // ignite_ready should stay high for at least 4 cycles
end
RETURN_VAL2:begin
if(ACC_IRQ_READY)begin
state <= RETURN_VAL3;
end
end
RETURN_VAL3:begin
state <= RETURN_VAL4;
end
RETURN_VAL4:begin
state <= RETURN_VAL5;
end
RETURN_VAL5:begin
state <= IDLE;
end
default: state <= IDLE;
endcase
end
end
wire[31:0] sub_result;
wire comp_result;
wire[31:0] add_result_wire;
wire[31:0] add_result_wire;
reg add_start;
reg comp_start;
reg sub_start;
wire add_result_valid;
wire comp_result_valid;
wire sub_result_valid;
floating_point_add floating_point_add(
.aclk (ACLK),
.s_axis_a_tdata (lut),
.s_axis_a_tvalid (add_start),
.s_axis_b_tdata (o),
.s_axis_b_tvalid (add_start),
.m_axis_result_tdata (add_result_wire),
.m_axis_result_tvalid (add_result_valid)
);
floating_point_comp floating_point_comp(
.aclk (ACLK),
.s_axis_a_tdata (o),
.s_axis_a_tvalid (comp_start),
.s_axis_b_tdata (thr),
.s_axis_b_tvalid (comp_start),
.m_axis_result_tdata (comp_result),
.m_axis_result_tvalid (comp_result_valid)
);
floating_point_sub floating_point_sub(
.aclk (ACLK),
.s_axis_a_tdata (o),
.s_axis_a_tvalid (sub_start),
.s_axis_b_tdata (thr_last),
.s_axis_b_tvalid (sub_start),
.m_axis_result_tdata (sub_result),
.m_axis_result_tvalid (sub_result_valid)
);
endmodule

View File

@ -0,0 +1,48 @@
module custom_apb_button #(
parameter ADDRWIDTH = 12)
(
//SYSTEM
input wire pclk,
input wire presetn,
//APB
input wire psel,
input wire [ADDRWIDTH-1:0] paddr,
input wire penable,
input wire pwrite,
input wire [31:0] pwdata,
output reg [31:0] prdata,
output wire pready,
output wire pslverr,
//INTERFACE
input wire state1
);
assign pready = 1'b1; //always ready. Can be customized to support waitstate if required.
assign pslverr = 1'b0; //alwyas OKAY. Can be customized to support error response if required.
reg [31:0] btn_reg;
always @ (posedge pclk or negedge presetn)
begin
if(~presetn) begin
btn_reg <= 32'h1;
end else begin
btn_reg <= {{31{1'b0}},state1};
end
end
always @(posedge pclk or negedge presetn)
begin
if (~presetn) begin
prdata <= 32'h01;
end else begin
prdata <= btn_reg;
end
end
endmodule

View File

@ -0,0 +1,350 @@
module aq_axi_master_cam(
// Reset, Clock
input ARESETN,
input ACLK,
// Master Write Address
output [0:0] M_AXI_AWID,
output [31:0] M_AXI_AWADDR,
output [7:0] M_AXI_AWLEN, // Burst Length: 0-255
output [2:0] M_AXI_AWSIZE, // Burst Size: Fixed 2'b011
output [1:0] M_AXI_AWBURST, // Burst Type: Fixed 2'b01(Incremental Burst)
output M_AXI_AWLOCK, // Lock: Fixed 2'b00
output [3:0] M_AXI_AWCACHE, // Cache: Fiex 2'b0011
output [2:0] M_AXI_AWPROT, // Protect: Fixed 2'b000
output [3:0] M_AXI_AWQOS, // QoS: Fixed 2'b0000
output [0:0] M_AXI_AWUSER, // User: Fixed 32'd0
output M_AXI_AWVALID,
input M_AXI_AWREADY,
// Master Write Data
output [31:0] M_AXI_WDATA,
output [7:0] M_AXI_WSTRB,
output M_AXI_WLAST,
output [0:0] M_AXI_WUSER,
output M_AXI_WVALID,
input M_AXI_WREADY,
// Master Write Response
input [0:0] M_AXI_BID,
input [1:0] M_AXI_BRESP,
input [0:0] M_AXI_BUSER,
input M_AXI_BVALID,
output M_AXI_BREADY,
// Master Read Address
output [0:0] M_AXI_ARID,
output [31:0] M_AXI_ARADDR,
output [7:0] M_AXI_ARLEN,
output [2:0] M_AXI_ARSIZE,
output [1:0] M_AXI_ARBURST,
output [1:0] M_AXI_ARLOCK,
output [3:0] M_AXI_ARCACHE,
output [2:0] M_AXI_ARPROT,
output [3:0] M_AXI_ARQOS,
output [0:0] M_AXI_ARUSER,
output M_AXI_ARVALID,
input M_AXI_ARREADY,
// Master Read Data
input [0:0] M_AXI_RID,
input [31:0] M_AXI_RDATA,
input [1:0] M_AXI_RRESP,
input M_AXI_RLAST,
input [0:0] M_AXI_RUSER,
input M_AXI_RVALID,
output M_AXI_RREADY,
// Local Bus
input MASTER_RST,
input WR_START,
input [31:0] WR_ADRS,
input [31:0] WR_LEN,
output WR_READY,
output WR_FIFO_RE,
input WR_FIFO_EMPTY,
input WR_FIFO_AEMPTY,
input [31:0] WR_FIFO_DATA,
output WR_DONE,
input RD_START,
input [31:0] RD_ADRS,
input [31:0] RD_LEN,
output RD_READY,
output RD_FIFO_WE,
input RD_FIFO_FULL,
input RD_FIFO_AFULL,
output [31:0] RD_FIFO_DATA,
output RD_DONE,
output [31:0] DEBUG
);
localparam S_WR_IDLE = 3'd0;
localparam S_WA_WAIT = 3'd1;
localparam S_WA_START = 3'd2;
localparam S_WD_WAIT = 3'd3;
localparam S_WD_PROC = 3'd4;
localparam S_WR_WAIT = 3'd5;
localparam S_WR_DONE = 3'd6;
reg [2:0] wr_state;
reg [31:0] reg_wr_adrs;
reg [31:0] reg_wr_len;
reg reg_awvalid, reg_wvalid, reg_w_last;
reg [7:0] reg_w_len;
reg [7:0] reg_w_stb;
reg [1:0] reg_wr_status;
reg [3:0] reg_w_count, reg_r_count;
reg [7:0] rd_chkdata, wr_chkdata;
reg [1:0] resp;
reg rd_first_data;
reg rd_fifo_enable;
reg[31:0] rd_fifo_cnt;
assign WR_DONE = (wr_state == S_WR_DONE);
assign WR_FIFO_RE = rd_first_data | (reg_wvalid & ~WR_FIFO_EMPTY & M_AXI_WREADY & rd_fifo_enable);
always @(posedge ACLK or negedge ARESETN)
begin
if(!ARESETN)
rd_fifo_cnt <= 32'd0;
else if(WR_FIFO_RE)
rd_fifo_cnt <= rd_fifo_cnt + 32'd1;
else if(wr_state == S_WR_IDLE)
rd_fifo_cnt <= 32'd0;
end
always @(posedge ACLK or negedge ARESETN)
begin
if(!ARESETN)
rd_fifo_enable <= 1'b0;
else if(wr_state == S_WR_IDLE && WR_START)
rd_fifo_enable <= 1'b1;
else if(WR_FIFO_RE && (rd_fifo_cnt == WR_LEN[31:3] - 32'd1) )
rd_fifo_enable <= 1'b0;
end
// Write State
always @(posedge ACLK or negedge ARESETN) begin
if(!ARESETN) begin
wr_state <= S_WR_IDLE;
reg_wr_adrs[31:0] <= 32'd0;
reg_wr_len[31:0] <= 32'd0;
reg_awvalid <= 1'b0;
reg_wvalid <= 1'b0;
reg_w_last <= 1'b0;
reg_w_len[7:0] <= 8'd0;
reg_w_stb[7:0] <= 8'd0;
reg_wr_status[1:0] <= 2'd0;
reg_w_count[3:0] <= 4'd0;
reg_r_count[3:0] <= 4'd0;
wr_chkdata <= 8'd0;
rd_chkdata <= 8'd0;
resp <= 2'd0;
rd_first_data <= 1'b0;
end else begin
if(MASTER_RST) begin
wr_state <= S_WR_IDLE;
end else begin
case(wr_state)
S_WR_IDLE: begin
if(WR_START) begin
wr_state <= S_WA_WAIT;
reg_wr_adrs[31:0] <= WR_ADRS[31:0];
reg_wr_len[31:0] <= WR_LEN[31:0] -32'd1;
rd_first_data <= 1'b1;
end
reg_awvalid <= 1'b0;
reg_wvalid <= 1'b0;
reg_w_last <= 1'b0;
reg_w_len[7:0] <= 8'd0;
reg_w_stb[7:0] <= 8'd0;
reg_wr_status[1:0] <= 2'd0;
end
S_WA_WAIT: begin
if(!WR_FIFO_AEMPTY | (reg_wr_len[31:11] == 21'd0)) begin
wr_state <= S_WA_START;
end
rd_first_data <= 1'b0;
end
S_WA_START: begin
wr_state <= S_WD_WAIT;
reg_awvalid <= 1'b1;
reg_wr_len[31:11] <= reg_wr_len[31:11] - 21'd1;
if(reg_wr_len[31:11] != 21'd0) begin
reg_w_len[7:0] <= 8'hFF;
reg_w_last <= 1'b0;
reg_w_stb[7:0] <= 8'hFF;
end else begin
reg_w_len[7:0] <= reg_wr_len[10:3];
reg_w_last <= 1'b1;
reg_w_stb[7:0] <= 8'hFF;
end
end
S_WD_WAIT: begin
if(M_AXI_AWREADY) begin
wr_state <= S_WD_PROC;
reg_awvalid <= 1'b0;
reg_wvalid <= 1'b1;
end
end
S_WD_PROC: begin
if(M_AXI_WREADY & ~WR_FIFO_EMPTY) begin
if(reg_w_len[7:0] == 8'd0) begin
wr_state <= S_WR_WAIT;
reg_wvalid <= 1'b0;
reg_w_stb[7:0] <= 8'h00;
end else begin
reg_w_len[7:0] <= reg_w_len[7:0] -8'd1;
end
end
end
S_WR_WAIT: begin
if(M_AXI_BVALID) begin
reg_wr_status[1:0] <= reg_wr_status[1:0] | M_AXI_BRESP[1:0];
if(reg_w_last) begin
wr_state <= S_WR_DONE;
end else begin
wr_state <= S_WA_WAIT;
reg_wr_adrs[31:0] <= reg_wr_adrs[31:0] + 32'd2048;
end
end
end
S_WR_DONE: begin
wr_state <= S_WR_IDLE;
end
default: begin
wr_state <= S_WR_IDLE;
end
endcase
end
end
end
assign M_AXI_AWID = 1'b0;
assign M_AXI_AWADDR[31:0] = reg_wr_adrs[31:0];
assign M_AXI_AWLEN[7:0] = reg_w_len[7:0];
assign M_AXI_AWSIZE[2:0] = 2'b010;
assign M_AXI_AWBURST[1:0] = 2'b01;
assign M_AXI_AWLOCK = 1'b0;
assign M_AXI_AWCACHE[3:0] = 4'b0011;
assign M_AXI_AWPROT[2:0] = 3'b000;
assign M_AXI_AWQOS[3:0] = 4'b0000;
assign M_AXI_AWUSER[0] = 1'b1;
assign M_AXI_AWVALID = reg_awvalid;
assign M_AXI_WDATA[31:0] = WR_FIFO_DATA[31:0];
assign M_AXI_WSTRB[7:0] = (reg_wvalid & ~WR_FIFO_EMPTY)?8'hFF:8'h00;
assign M_AXI_WLAST = (reg_w_len[7:0] == 8'd0)?1'b1:1'b0;
assign M_AXI_WUSER = 1;
assign M_AXI_WVALID = reg_wvalid & ~WR_FIFO_EMPTY;
assign M_AXI_BREADY = M_AXI_BVALID;
assign WR_READY = (wr_state == S_WR_IDLE)?1'b1:1'b0;
localparam S_RD_IDLE = 3'd0;
localparam S_RA_WAIT = 3'd1;
localparam S_RA_START = 3'd2;
localparam S_RD_WAIT = 3'd3;
localparam S_RD_PROC = 3'd4;
localparam S_RD_DONE = 3'd5;
reg [2:0] rd_state;
reg [31:0] reg_rd_adrs;
reg [31:0] reg_rd_len;
reg reg_arvalid, reg_r_last;
reg [7:0] reg_r_len;
assign RD_DONE = (rd_state == S_RD_DONE) ;
// Read State
always @(posedge ACLK or negedge ARESETN) begin
if(!ARESETN) begin
rd_state <= S_RD_IDLE;
reg_rd_adrs[31:0] <= 32'd0;
reg_rd_len[31:0] <= 32'd0;
reg_arvalid <= 1'b0;
reg_r_len[7:0] <= 8'd0;
end else begin
case(rd_state)
S_RD_IDLE: begin
if(RD_START) begin
rd_state <= S_RA_WAIT;
reg_rd_adrs[31:0] <= RD_ADRS[31:0];
reg_rd_len[31:0] <= RD_LEN[31:0] -32'd1;
end
reg_arvalid <= 1'b0;
reg_r_len[7:0] <= 8'd0;
end
S_RA_WAIT: begin
if(~RD_FIFO_AFULL) begin
rd_state <= S_RA_START;
end
end
S_RA_START: begin
rd_state <= S_RD_WAIT;
reg_arvalid <= 1'b1;
reg_rd_len[31:11] <= reg_rd_len[31:11] -21'd1;
if(reg_rd_len[31:11] != 21'd0) begin
reg_r_last <= 1'b0;
reg_r_len[7:0] <= 8'd255;
end else begin
reg_r_last <= 1'b1;
reg_r_len[7:0] <= reg_rd_len[10:3];
end
end
S_RD_WAIT: begin
if(M_AXI_ARREADY) begin
rd_state <= S_RD_PROC;
reg_arvalid <= 1'b0;
end
end
S_RD_PROC: begin
if(M_AXI_RVALID) begin
if(M_AXI_RLAST) begin
if(reg_r_last) begin
rd_state <= S_RD_DONE;
end else begin
rd_state <= S_RA_WAIT;
reg_rd_adrs[31:0] <= reg_rd_adrs[31:0] + 32'd2048;
end
end else begin
reg_r_len[7:0] <= reg_r_len[7:0] -8'd1;
end
end
end
S_RD_DONE:begin
rd_state <= S_RD_IDLE;
end
endcase
end
end
// Master Read Address
assign M_AXI_ARID = 1'b0;
assign M_AXI_ARADDR[31:0] = reg_rd_adrs[31:0];
assign M_AXI_ARLEN[7:0] = reg_r_len[7:0];
assign M_AXI_ARSIZE[2:0] = 3'b010;
assign M_AXI_ARBURST[1:0] = 2'b01;
assign M_AXI_ARLOCK = 1'b0;
assign M_AXI_ARCACHE[3:0] = 4'b0011;
assign M_AXI_ARPROT[2:0] = 3'b000;
assign M_AXI_ARQOS[3:0] = 4'b0000;
assign M_AXI_ARUSER[0] = 1'b1;
assign M_AXI_ARVALID = reg_arvalid;
assign M_AXI_RREADY = M_AXI_RVALID & ~RD_FIFO_FULL;
assign RD_READY = (rd_state == S_RD_IDLE)?1'b1:1'b0;
assign RD_FIFO_WE = M_AXI_RVALID;
assign RD_FIFO_DATA[31:0] = M_AXI_RDATA[31:0];
assign DEBUG[31:0] = {reg_wr_len[31:8],
1'd0, wr_state[2:0], 1'd0, rd_state[2:0]};
endmodule

View File

@ -0,0 +1,55 @@
module cmos_8_16bit(
input rst,
input pclk,
input [7:0] pdata_i,
input de_i,
output reg[15:0] pdata_o,
output reg hblank,
output reg de_o
);
reg[7:0] pdata_i_d0;
reg[11:0] x_cnt;
always@(posedge pclk)
begin
pdata_i_d0 <= pdata_i;
end
always@(posedge pclk or posedge rst)
begin
if(rst)
x_cnt <= 12'd0;
else if(de_i)
x_cnt <= x_cnt + 12'd1;
else
x_cnt <= 12'd0;
end
always@(posedge pclk or posedge rst)
begin
if(rst)
de_o <= 1'b0;
else if(de_i && x_cnt[0])
de_o <= 1'b1;
else
de_o <= 1'b0;
end
always@(posedge pclk or posedge rst)
begin
if(rst)
hblank <= 1'b0;
else
hblank <= de_i;
end
always@(posedge pclk or posedge rst)
begin
if(rst)
pdata_o <= 16'd0;
else if(de_i && x_cnt[0])
pdata_o <= {pdata_i_d0,pdata_i};
else
pdata_o <= 16'd0;
end
endmodule

View File

@ -0,0 +1,56 @@
module cmos_write_req_gen(
input rst,
input pclk,
input cmos_vsync,
output reg write_req,
// output reg write_addr_index,
// output reg read_addr_index,
input write_req_ack
);
reg cmos_vsync_d0;
reg cmos_vsync_d1;
always@(posedge pclk or posedge rst)
begin
if(rst == 1'b1)
begin
cmos_vsync_d0 <= 1'b0;
cmos_vsync_d1 <= 1'b0;
end
else
begin
cmos_vsync_d0 <= cmos_vsync;
cmos_vsync_d1 <= cmos_vsync_d0;
end
end
always@(posedge pclk or posedge rst)
begin
if(rst == 1'b1)
begin
write_req <= 1'b0;
end
else if(cmos_vsync_d0 == 1'b1 && cmos_vsync_d1 == 1'b0)
begin
write_req <= 1'b1;
end
else if(write_req_ack == 1'b1)
write_req <= 1'b0;
end
// always@(posedge pclk or posedge rst)
// begin
// if(rst == 1'b1)
// write_addr_index <= 1'b0;
// else if(cmos_vsync_d0 == 1'b1 && cmos_vsync_d1 == 1'b0)
// write_addr_index <= write_addr_index + 1'd1;
// end
// always@(posedge pclk or posedge rst)
// begin
// if(rst == 1'b1)
// read_addr_index <= 1'b0;
// else if(cmos_vsync_d0 == 1'b1 && cmos_vsync_d1 == 1'b0)
// read_addr_index <= write_addr_index;
// end
endmodule

View File

@ -0,0 +1,357 @@
//////////////////////////////////////////////////////////////////////////////////
// color bar generator module //
// //
// Author: meisq //
// msq@qq.com //
// ALINX(shanghai) Technology Co.,Ltd //
// heijin //
// WEB: http://www.alinx.cn/ //
// BBS: http://www.heijin.org/ //
// //
//////////////////////////////////////////////////////////////////////////////////
// //
// Copyright (c) 2017,ALINX(shanghai) Technology Co.,Ltd //
// All rights reserved //
// //
// 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. //
// //
//////////////////////////////////////////////////////////////////////////////////
//================================================================================
// Revision History:
// Date By Revision Change Description
//--------------------------------------------------------------------------------
//2013/4/16 1.0 Original
//2013/4/18 1.1 vs timing
//2013/5/7 1.2 remove some warning
//2017/7/17 1.3
//*******************************************************************************/
`include "video_define.v"
module color_bar(
input clk, //pixel clock
input rst, //reset signal high active
output hs, //horizontal synchronization
output vs, //vertical synchronization
output de, //video valid
output[7:0] rgb_r, //video red data
output[7:0] rgb_g, //video green data
output[7:0] rgb_b //video blue data
);
//video timing parameter definition
`ifdef VIDEO_1280_720
parameter H_ACTIVE = 16'd1280; //horizontal active time (pixels)
parameter H_FP = 16'd110; //horizontal front porch (pixels)
parameter H_SYNC = 16'd40; //horizontal sync time(pixels)
parameter H_BP = 16'd220; //horizontal back porch (pixels)
parameter V_ACTIVE = 16'd720; //vertical active Time (lines)
parameter V_FP = 16'd5; //vertical front porch (lines)
parameter V_SYNC = 16'd5; //vertical sync time (lines)
parameter V_BP = 16'd20; //vertical back porch (lines)
parameter HS_POL = 1'b1; //horizontal sync polarity, 1 : POSITIVE,0 : NEGATIVE;
parameter VS_POL = 1'b1; //vertical sync polarity, 1 : POSITIVE,0 : NEGATIVE;
`endif
//480x272 9Mhz
`ifdef VIDEO_480_272
parameter H_ACTIVE = 16'd480;
parameter H_FP = 16'd2;
parameter H_SYNC = 16'd41;
parameter H_BP = 16'd2;
parameter V_ACTIVE = 16'd272;
parameter V_FP = 16'd2;
parameter V_SYNC = 16'd10;
parameter V_BP = 16'd2;
parameter HS_POL = 1'b0;
parameter VS_POL = 1'b0;
`endif
//640x480 25.175Mhz
`ifdef VIDEO_640_480
parameter H_ACTIVE = 16'd640;
parameter H_FP = 16'd16;
parameter H_SYNC = 16'd96;
parameter H_BP = 16'd48;
parameter V_ACTIVE = 16'd480;
parameter V_FP = 16'd10;
parameter V_SYNC = 16'd2;
parameter V_BP = 16'd33;
parameter HS_POL = 1'b0;
parameter VS_POL = 1'b0;
`endif
//800x480 33Mhz
`ifdef VIDEO_800_480
parameter H_ACTIVE = 16'd800;
parameter H_FP = 16'd40;
parameter H_SYNC = 16'd128;
parameter H_BP = 16'd88;
parameter V_ACTIVE = 16'd480;
parameter V_FP = 16'd1;
parameter V_SYNC = 16'd3;
parameter V_BP = 16'd21;
parameter HS_POL = 1'b0;
parameter VS_POL = 1'b0;
`endif
//800x600 40Mhz
`ifdef VIDEO_800_600
parameter H_ACTIVE = 16'd800;
parameter H_FP = 16'd40;
parameter H_SYNC = 16'd128;
parameter H_BP = 16'd88;
parameter V_ACTIVE = 16'd600;
parameter V_FP = 16'd1;
parameter V_SYNC = 16'd4;
parameter V_BP = 16'd23;
parameter HS_POL = 1'b1;
parameter VS_POL = 1'b1;
`endif
//1024x768 65Mhz
`ifdef VIDEO_1024_768
parameter H_ACTIVE = 16'd1024;
parameter H_FP = 16'd24;
parameter H_SYNC = 16'd136;
parameter H_BP = 16'd160;
parameter V_ACTIVE = 16'd768;
parameter V_FP = 16'd3;
parameter V_SYNC = 16'd6;
parameter V_BP = 16'd29;
parameter HS_POL = 1'b0;
parameter VS_POL = 1'b0;
`endif
//1920x1080 148.5Mhz
`ifdef VIDEO_1920_1080
parameter H_ACTIVE = 16'd1920;
parameter H_FP = 16'd88;
parameter H_SYNC = 16'd44;
parameter H_BP = 16'd148;
parameter V_ACTIVE = 16'd1080;
parameter V_FP = 16'd4;
parameter V_SYNC = 16'd5;
parameter V_BP = 16'd36;
parameter HS_POL = 1'b1;
parameter VS_POL = 1'b1;
`endif
parameter H_TOTAL = H_ACTIVE + H_FP + H_SYNC + H_BP;//horizontal total time (pixels)
parameter V_TOTAL = V_ACTIVE + V_FP + V_SYNC + V_BP;//vertical total time (lines)
//define the RGB values for 8 colors
parameter WHITE_R = 8'hff;
parameter WHITE_G = 8'hff;
parameter WHITE_B = 8'hff;
parameter YELLOW_R = 8'hff;
parameter YELLOW_G = 8'hff;
parameter YELLOW_B = 8'h00;
parameter CYAN_R = 8'h00;
parameter CYAN_G = 8'hff;
parameter CYAN_B = 8'hff;
parameter GREEN_R = 8'h00;
parameter GREEN_G = 8'hff;
parameter GREEN_B = 8'h00;
parameter MAGENTA_R = 8'hff;
parameter MAGENTA_G = 8'h00;
parameter MAGENTA_B = 8'hff;
parameter RED_R = 8'hff;
parameter RED_G = 8'h00;
parameter RED_B = 8'h00;
parameter BLUE_R = 8'h00;
parameter BLUE_G = 8'h00;
parameter BLUE_B = 8'hff;
parameter BLACK_R = 8'h00;
parameter BLACK_G = 8'h00;
parameter BLACK_B = 8'h00;
reg hs_reg; //horizontal sync register
reg vs_reg; //vertical sync register
reg hs_reg_d0; //delay 1 clock of 'hs_reg'
reg vs_reg_d0; //delay 1 clock of 'vs_reg'
reg[11:0] h_cnt; //horizontal counter
reg[11:0] v_cnt; //vertical counter
reg[11:0] active_x; //video x position
reg[11:0] active_y; //video y position
reg[7:0] rgb_r_reg; //video red data register
reg[7:0] rgb_g_reg; //video green data register
reg[7:0] rgb_b_reg; //video blue data register
reg h_active; //horizontal video active
reg v_active; //vertical video active
wire video_active; //video active(horizontal active and vertical active)
reg video_active_d0; //delay 1 clock of video_active
assign hs = hs_reg_d0;
assign vs = vs_reg_d0;
assign video_active = h_active & v_active;
assign de = video_active_d0;
assign rgb_r = rgb_r_reg;
assign rgb_g = rgb_g_reg;
assign rgb_b = rgb_b_reg;
always@(posedge clk or posedge rst)
begin
if(rst == 1'b1)
begin
hs_reg_d0 <= 1'b0;
vs_reg_d0 <= 1'b0;
video_active_d0 <= 1'b0;
end
else
begin
hs_reg_d0 <= hs_reg;
vs_reg_d0 <= vs_reg;
video_active_d0 <= video_active;
end
end
always@(posedge clk or posedge rst)
begin
if(rst == 1'b1)
h_cnt <= 12'd0;
else if(h_cnt == H_TOTAL - 1)//horizontal counter maximum value
h_cnt <= 12'd0;
else
h_cnt <= h_cnt + 12'd1;
end
always@(posedge clk or posedge rst)
begin
if(rst == 1'b1)
active_x <= 12'd0;
else if(h_cnt >= H_FP + H_SYNC + H_BP - 1)//horizontal video active
active_x <= h_cnt - (H_FP[11:0] + H_SYNC[11:0] + H_BP[11:0] - 12'd1);
else
active_x <= active_x;
end
always@(posedge clk or posedge rst)
begin
if(rst == 1'b1)
v_cnt <= 12'd0;
else if(h_cnt == H_FP - 1)//horizontal sync time
if(v_cnt == V_TOTAL - 1)//vertical counter maximum value
v_cnt <= 12'd0;
else
v_cnt <= v_cnt + 12'd1;
else
v_cnt <= v_cnt;
end
always@(posedge clk or posedge rst)
begin
if(rst == 1'b1)
hs_reg <= 1'b0;
else if(h_cnt == H_FP - 1)//horizontal sync begin
hs_reg <= HS_POL;
else if(h_cnt == H_FP + H_SYNC - 1)//horizontal sync end
hs_reg <= ~hs_reg;
else
hs_reg <= hs_reg;
end
always@(posedge clk or posedge rst)
begin
if(rst == 1'b1)
h_active <= 1'b0;
else if(h_cnt == H_FP + H_SYNC + H_BP - 1)//horizontal active begin
h_active <= 1'b1;
else if(h_cnt == H_TOTAL - 1)//horizontal active end
h_active <= 1'b0;
else
h_active <= h_active;
end
always@(posedge clk or posedge rst)
begin
if(rst == 1'b1)
vs_reg <= 1'd0;
else if((v_cnt == V_FP - 1) && (h_cnt == H_FP - 1))//vertical sync begin
vs_reg <= HS_POL;
else if((v_cnt == V_FP + V_SYNC - 1) && (h_cnt == H_FP - 1))//vertical sync end
vs_reg <= ~vs_reg;
else
vs_reg <= vs_reg;
end
always@(posedge clk or posedge rst)
begin
if(rst == 1'b1)
v_active <= 1'd0;
else if((v_cnt == V_FP + V_SYNC + V_BP - 1) && (h_cnt == H_FP - 1))//vertical active begin
v_active <= 1'b1;
else if((v_cnt == V_TOTAL - 1) && (h_cnt == H_FP - 1)) //vertical active end
v_active <= 1'b0;
else
v_active <= v_active;
end
always@(posedge clk or posedge rst)
begin
if(rst == 1'b1)
begin
rgb_r_reg <= 8'h00;
rgb_g_reg <= 8'h00;
rgb_b_reg <= 8'h00;
end
else if(video_active)
if(active_x == 12'd0)
begin
rgb_r_reg <= WHITE_R;
rgb_g_reg <= WHITE_G;
rgb_b_reg <= WHITE_B;
end
else if(active_x == (H_ACTIVE/8) * 1)
begin
rgb_r_reg <= YELLOW_R;
rgb_g_reg <= YELLOW_G;
rgb_b_reg <= YELLOW_B;
end
else if(active_x == (H_ACTIVE/8) * 2)
begin
rgb_r_reg <= CYAN_R;
rgb_g_reg <= CYAN_G;
rgb_b_reg <= CYAN_B;
end
else if(active_x == (H_ACTIVE/8) * 3)
begin
rgb_r_reg <= GREEN_R;
rgb_g_reg <= GREEN_G;
rgb_b_reg <= GREEN_B;
end
else if(active_x == (H_ACTIVE/8) * 4)
begin
rgb_r_reg <= MAGENTA_R;
rgb_g_reg <= MAGENTA_G;
rgb_b_reg <= MAGENTA_B;
end
else if(active_x == (H_ACTIVE/8) * 5)
begin
rgb_r_reg <= RED_R;
rgb_g_reg <= RED_G;
rgb_b_reg <= RED_B;
end
else if(active_x == (H_ACTIVE/8) * 6)
begin
rgb_r_reg <= BLUE_R;
rgb_g_reg <= BLUE_G;
rgb_b_reg <= BLUE_B;
end
else if(active_x == (H_ACTIVE/8) * 7)
begin
rgb_r_reg <= BLACK_R;
rgb_g_reg <= BLACK_G;
rgb_b_reg <= BLACK_B;
end
else
begin
rgb_r_reg <= rgb_r_reg;
rgb_g_reg <= rgb_g_reg;
rgb_b_reg <= rgb_b_reg;
end
else
begin
rgb_r_reg <= 8'h00;
rgb_g_reg <= 8'h00;
rgb_b_reg <= 8'h00;
end
end
endmodule

View File

@ -0,0 +1,66 @@
`timescale 1 ps / 1ps
module dvi_encoder
(
input pixelclk, // system clock
input pixelclk5x, // system clock x5
input rstin, // reset
input[7:0] blue_din, // Blue data in
input[7:0] green_din, // Green data in
input[7:0] red_din, // Red data in
input hsync, // hsync data
input vsync, // vsync data
input de, // data enable
output tmds_clk_p,
output tmds_clk_n,
output[2:0] tmds_data_p, //rgb
output[2:0] tmds_data_n //rgb
);
wire [9:0] red ;
wire [9:0] green ;
wire [9:0] blue ;
encode encb (
.clkin (pixelclk),
.rstin (rstin),
.din (blue_din),
.c0 (hsync),
.c1 (vsync),
.de (de),
.dout (blue)) ;
encode encr (
.clkin (pixelclk),
.rstin (rstin),
.din (green_din),
.c0 (1'b0),
.c1 (1'b0),
.de (de),
.dout (green)) ;
encode encg (
.clkin (pixelclk),
.rstin (rstin),
.din (red_din),
.c0 (1'b0),
.c1 (1'b0),
.de (de),
.dout (red)) ;
serdes_4b_10to1 serdes_4b_10to1_m0(
.clk (pixelclk ),// clock input
.clkx5 (pixelclk5x ),// 5x clock input
.datain_0 (blue ),// input data for serialisation
.datain_1 (green ),// input data for serialisation
.datain_2 (red ),// input data for serialisation
.datain_3 (10'b1111100000 ),// input data for serialisation
.dataout_0_p (tmds_data_p[0] ),// out DDR data
.dataout_0_n (tmds_data_n[0] ),// out DDR data
.dataout_1_p (tmds_data_p[1] ),// out DDR data
.dataout_1_n (tmds_data_n[1] ),// out DDR data
.dataout_2_p (tmds_data_p[2] ),// out DDR data
.dataout_2_n (tmds_data_n[2] ),// out DDR data
.dataout_3_p (tmds_clk_p ),// out DDR data
.dataout_3_n (tmds_clk_n ) // out DDR data
) ;
endmodule

View File

@ -0,0 +1,177 @@
//////////////////////////////////////////////////////////////////////////////
//
// Xilinx, Inc. 2008 www.xilinx.com
//
//////////////////////////////////////////////////////////////////////////////
//
// File name : encode.v
//
// Description : TMDS encoder
//
// Date - revision : Jan. 2008 - v 1.0
//
// Author : Bob Feng
//
// Disclaimer: LIMITED WARRANTY AND DISCLAMER. These designs are
// provided to you "as is". Xilinx and its licensors make and you
// receive no warranties or conditions, express, implied,
// statutory or otherwise, and Xilinx specifically disclaims any
// implied warranties of merchantability, non-infringement,or
// fitness for a particular purpose. Xilinx does not warrant that
// the functions contained in these designs will meet your
// requirements, or that the operation of these designs will be
// uninterrupted or error free, or that defects in the Designs
// will be corrected. Furthermore, Xilinx does not warrantor
// make any representations regarding use or the results of the
// use of the designs in terms of correctness, accuracy,
// reliability, or otherwise.
//
// LIMITATION OF LIABILITY. In no event will Xilinx or its
// licensors be liable for any loss of data, lost profits,cost
// or procurement of substitute goods or services, or for any
// special, incidental, consequential, or indirect damages
// arising from the use or operation of the designs or
// accompanying documentation, however caused and on any theory
// of liability. This limitation will apply even if Xilinx
// has been advised of the possibility of such damage. This
// limitation shall apply not-withstanding the failure of the
// essential purpose of any limited remedies herein.
//
// Copyright ? 2006 Xilinx, Inc.
// All rights reserved
//
//////////////////////////////////////////////////////////////////////////////
`timescale 1 ps / 1ps
module encode (
input clkin, // pixel clock input
input rstin, // async. reset input (active high)
input [7:0] din, // data inputs: expect registered
input c0, // c0 input
input c1, // c1 input
input de, // de input
output reg [9:0] dout // data outputs
);
////////////////////////////////////////////////////////////
// Counting number of 1s and 0s for each incoming pixel
// component. Pipe line the result.
// Register Data Input so it matches the pipe lined adder
// output
////////////////////////////////////////////////////////////
reg [3:0] n1d; //number of 1s in din
reg [7:0] din_q;
always @ (posedge clkin) begin
n1d <=#1 din[0] + din[1] + din[2] + din[3] + din[4] + din[5] + din[6] + din[7];
din_q <=#1 din;
end
///////////////////////////////////////////////////////
// Stage 1: 8 bit -> 9 bit
// Refer to DVI 1.0 Specification, page 29, Figure 3-5
///////////////////////////////////////////////////////
wire decision1;
assign decision1 = (n1d > 4'h4) | ((n1d == 4'h4) & (din_q[0] == 1'b0));
wire [8:0] q_m;
assign q_m[0] = din_q[0];
assign q_m[1] = (decision1) ? (q_m[0] ^~ din_q[1]) : (q_m[0] ^ din_q[1]);
assign q_m[2] = (decision1) ? (q_m[1] ^~ din_q[2]) : (q_m[1] ^ din_q[2]);
assign q_m[3] = (decision1) ? (q_m[2] ^~ din_q[3]) : (q_m[2] ^ din_q[3]);
assign q_m[4] = (decision1) ? (q_m[3] ^~ din_q[4]) : (q_m[3] ^ din_q[4]);
assign q_m[5] = (decision1) ? (q_m[4] ^~ din_q[5]) : (q_m[4] ^ din_q[5]);
assign q_m[6] = (decision1) ? (q_m[5] ^~ din_q[6]) : (q_m[5] ^ din_q[6]);
assign q_m[7] = (decision1) ? (q_m[6] ^~ din_q[7]) : (q_m[6] ^ din_q[7]);
assign q_m[8] = (decision1) ? 1'b0 : 1'b1;
/////////////////////////////////////////////////////////
// Stage 2: 9 bit -> 10 bit
// Refer to DVI 1.0 Specification, page 29, Figure 3-5
/////////////////////////////////////////////////////////
reg [3:0] n1q_m, n0q_m; // number of 1s and 0s for q_m
always @ (posedge clkin) begin
n1q_m <=#1 q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7];
n0q_m <=#1 4'h8 - (q_m[0] + q_m[1] + q_m[2] + q_m[3] + q_m[4] + q_m[5] + q_m[6] + q_m[7]);
end
parameter CTRLTOKEN0 = 10'b1101010100;
parameter CTRLTOKEN1 = 10'b0010101011;
parameter CTRLTOKEN2 = 10'b0101010100;
parameter CTRLTOKEN3 = 10'b1010101011;
reg [4:0] cnt; //disparity counter, MSB is the sign bit
wire decision2, decision3;
assign decision2 = (cnt == 5'h0) | (n1q_m == n0q_m);
/////////////////////////////////////////////////////////////////////////
// [(cnt > 0) and (N1q_m > N0q_m)] or [(cnt < 0) and (N0q_m > N1q_m)]
/////////////////////////////////////////////////////////////////////////
assign decision3 = (~cnt[4] & (n1q_m > n0q_m)) | (cnt[4] & (n0q_m > n1q_m));
////////////////////////////////////
// pipe line alignment
////////////////////////////////////
reg de_q, de_reg;
reg c0_q, c1_q;
reg c0_reg, c1_reg;
reg [8:0] q_m_reg;
always @ (posedge clkin) begin
de_q <=#1 de;
de_reg <=#1 de_q;
c0_q <=#1 c0;
c0_reg <=#1 c0_q;
c1_q <=#1 c1;
c1_reg <=#1 c1_q;
q_m_reg <=#1 q_m;
end
///////////////////////////////
// 10-bit out
// disparity counter
///////////////////////////////
always @ (posedge clkin or posedge rstin) begin
if(rstin) begin
dout <= 10'h0;
cnt <= 5'h0;
end else begin
if (de_reg) begin
if(decision2) begin
dout[9] <=#1 ~q_m_reg[8];
dout[8] <=#1 q_m_reg[8];
dout[7:0] <=#1 (q_m_reg[8]) ? q_m_reg[7:0] : ~q_m_reg[7:0];
cnt <=#1 (~q_m_reg[8]) ? (cnt + n0q_m - n1q_m) : (cnt + n1q_m - n0q_m);
end else begin
if(decision3) begin
dout[9] <=#1 1'b1;
dout[8] <=#1 q_m_reg[8];
dout[7:0] <=#1 ~q_m_reg;
cnt <=#1 cnt + {q_m_reg[8], 1'b0} + (n0q_m - n1q_m);
end else begin
dout[9] <=#1 1'b0;
dout[8] <=#1 q_m_reg[8];
dout[7:0] <=#1 q_m_reg[7:0];
cnt <=#1 cnt - {~q_m_reg[8], 1'b0} + (n1q_m - n0q_m);
end
end
end else begin
case ({c1_reg, c0_reg})
2'b00: dout <=#1 CTRLTOKEN0;
2'b01: dout <=#1 CTRLTOKEN1;
2'b10: dout <=#1 CTRLTOKEN2;
default: dout <=#1 CTRLTOKEN3;
endcase
cnt <=#1 5'h0;
end
end
end
endmodule

View File

@ -0,0 +1,227 @@
//////////////////////////////////////////////////////////////////////////////////
// Cross clock domain data reading frame with FIFO interface //
// //
// Author: meisq //
// msq@qq.com //
// ALINX(shanghai) Technology Co.,Ltd //
// heijin //
// WEB: http://www.alinx.cn/ //
// BBS: http://www.heijin.org/ //
// //
//////////////////////////////////////////////////////////////////////////////////
// //
// Copyright (c) 2017,ALINX(shanghai) Technology Co.,Ltd //
// All rights reserved //
// //
// 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. //
// //
//////////////////////////////////////////////////////////////////////////////////
//================================================================================
// Revision History:
// Date By Revision Change Description
//--------------------------------------------------------------------------------
// 2017/7/19 meisq 1.0 Original
//*******************************************************************************/
`timescale 1ns/1ps
module frame_fifo_read_cam
#
(
parameter MEM_DATA_BITS = 32,
parameter ADDR_BITS = 28,
parameter BUSRT_BITS = 10,
parameter FIFO_DEPTH = 256,
parameter BURST_SIZE = 128
)
(
input rst,
input mem_clk, // external memory controller user interface clock
output reg rd_burst_req, // to external memory controller,send out a burst read request
output reg[BUSRT_BITS - 1:0] rd_burst_len, // to external memory controller,data length of the burst read request, not bytes
output reg[ADDR_BITS - 1:0] rd_burst_addr, // to external memory controller,base address of the burst read request
input rd_burst_data_valid, // from external memory controller,read request data valid
input rd_burst_finish, // from external memory controller,burst read finish
input read_req, // data read module read request,keep '1' until read_req_ack = '1'
output reg read_req_ack, // data read module read request response
output read_finish, // data read module read request finish
input[ADDR_BITS - 1:0] read_addr_0, // data read module read request base address 0, used when read_addr_index = 0
input[ADDR_BITS - 1:0] read_addr_1, // data read module read request base address 1, used when read_addr_index = 1
input[ADDR_BITS - 1:0] read_addr_2, // data read module read request base address 1, used when read_addr_index = 2
input[ADDR_BITS - 1:0] read_addr_3, // data read module read request base address 1, used when read_addr_index = 3
input read_addr_index, // select valid base address from read_addr_0 read_addr_1
input[ADDR_BITS - 1:0] read_len, // data read module read request data length
output reg fifo_aclr, // to fifo asynchronous clear
input[15:0] wrusedw // from fifo write used words
);
localparam ONE = 256'd1; //256 bit '1' you can use ONE[n-1:0] for n bit '1'
localparam ZERO = 256'd0; //256 bit '0'
//read state machine code
localparam S_IDLE = 0; //idle state,waiting for frame read
localparam S_ACK = 1; //read request response
localparam S_WAIT = 2;
localparam S_CHECK_FIFO = 3; //check the FIFO status, ensure that there is enough space to burst read
localparam S_READ_BURST = 4; //begin a burst read
localparam S_READ_BURST_END = 5; //a burst read complete
localparam S_END = 6; //a frame of data is read to complete
reg read_req_d0; //asynchronous read request, synchronize to 'mem_clk' clock domain,first beat
reg read_req_d1; //second
reg read_req_d2; //third,Why do you need 3 ? Here's the design habit
reg[ADDR_BITS - 1:0] read_len_d0; //asynchronous read_len(read data length), synchronize to 'mem_clk' clock domain first
reg[ADDR_BITS - 1:0] read_len_d1; //second
reg[ADDR_BITS - 1:0] read_len_latch; //lock read data length
reg[ADDR_BITS - 1:0] read_cnt; //read data counter
reg[3:0] state; //state machine
reg read_addr_index_d0; //synchronize to 'mem_clk' clock domain first
reg read_addr_index_d1; //synchronize to 'mem_clk' clock domain second
reg[15:0] wait_cnt;
assign read_finish = (state == S_END) ? 1'b1 : 1'b0; //read finish at state 'S_END'
always@(posedge mem_clk or posedge rst)
begin
if(rst == 1'b1)
begin
read_req_d0 <= 1'b0;
read_req_d1 <= 1'b0;
read_req_d2 <= 1'b0;
read_len_d0 <= ZERO[ADDR_BITS - 1:0]; //equivalent to read_len_d0 <= 0;
read_len_d1 <= ZERO[ADDR_BITS - 1:0]; //equivalent to read_len_d1 <= 0;
read_addr_index_d0 <= 1'b0;
read_addr_index_d1 <= 1'b0;
end
else
begin
read_req_d0 <= read_req;
read_req_d1 <= read_req_d0;
read_req_d2 <= read_req_d1;
read_len_d0 <= read_len;
read_len_d1 <= read_len_d0;
read_addr_index_d0 <= read_addr_index;
read_addr_index_d1 <= read_addr_index_d0;
end
end
always@(posedge mem_clk or posedge rst)
begin
if(rst == 1'b1)
begin
state <= S_IDLE;
read_len_latch <= ZERO[ADDR_BITS - 1:0];
rd_burst_addr <= ZERO[ADDR_BITS - 1:0];
rd_burst_req <= 1'b0;
read_cnt <= ZERO[ADDR_BITS - 1:0];
fifo_aclr <= 1'b0;
rd_burst_len <= ZERO[BUSRT_BITS - 1:0];
read_req_ack <= 1'b0;
wait_cnt <= 16'd0;
end
else
case(state)
//idle state,waiting for read, read_req_d2 == '1' goto the 'S_ACK'
S_IDLE:
begin
if(read_req_d2 == 1'b1)
begin
state <= S_ACK;
end
read_req_ack <= 1'b0;
end
//'S_ACK' state completes the read request response, the FIFO reset, the address latch, and the data length latch
S_ACK:
begin
if(read_req_d2 == 1'b0)
begin
state <= S_WAIT;
wait_cnt <= 16'd0;
fifo_aclr <= 1'b0;
read_req_ack <= 1'b0;
end
else
begin
//read request response
read_req_ack <= 1'b1;
//FIFO reset
fifo_aclr <= 1'b1;
//select valid base address from read_addr_0 read_addr_1
if(read_addr_index_d1 == 2'd0)
rd_burst_addr <= read_addr_0;
else if(read_addr_index_d1 == 2'd1)
rd_burst_addr <= read_addr_1;
//latch data length
read_len_latch <= read_len_d1;
end
//read data counter reset, read_cnt <= 0;
read_cnt <= ZERO[ADDR_BITS - 1:0];
end
S_WAIT:
begin
if(wait_cnt >= 16'd200)
begin
state <= S_CHECK_FIFO;
end
else
begin
wait_cnt <= wait_cnt + 16'd1;
end
end
S_CHECK_FIFO:
begin
//if there is a read request at this time, enter the 'S_ACK' state
if(read_req_d2 == 1'b1)
begin
state <= S_ACK;
end
//if the FIFO space is a burst read request, goto burst read state
else if(wrusedw < (FIFO_DEPTH - BURST_SIZE - 2))
begin
state <= S_READ_BURST;
rd_burst_len <= BURST_SIZE[BUSRT_BITS - 1:0];
rd_burst_req <= 1'b1;
end
end
S_READ_BURST:
begin
if(rd_burst_data_valid)
rd_burst_req <= 1'b0;
//burst finish
if(rd_burst_finish == 1'b1)
begin
state <= S_READ_BURST_END;
//read counter + burst length
read_cnt <= read_cnt + BURST_SIZE[ADDR_BITS - 1:0];
//the next burst read address is generated
rd_burst_addr <= rd_burst_addr + BURST_SIZE[ADDR_BITS - 1:0];
end
end
S_READ_BURST_END:
begin
//if there is a read request at this time, enter the 'S_ACK' state
if(read_req_d2 == 1'b1)
begin
state <= S_ACK;
end
//if the read counter value is less than the frame length, continue read,
//otherwise the read is complete
else if(read_cnt < read_len_latch)
begin
state <= S_CHECK_FIFO;
end
else
begin
state <= S_END;
end
end
S_END:
begin
state <= S_IDLE;
end
default:
state <= S_IDLE;
endcase
end
endmodule

View File

@ -0,0 +1,241 @@
//利用fifo进行cmos得到的16位数的写入在对应的地址写过一帧后对该帧是否写入的标志赋值
//读出的部分是持续读出对该帧是否写入的标志特定内容进而可以在cmos写请求函数中对地址index产生影响
`timescale 1ns/1ps
module frame_fifo_write_cam
#
(
parameter MEM_DATA_BITS = 32,
parameter ADDR_BITS = 28,
parameter BUSRT_BITS = 10,
parameter BURST_SIZE = 128
)
(
input rst,
input mem_clk, // external memory controller user interface clock
output reg wr_burst_req, // to external memory controller,send out a burst write request
output reg[BUSRT_BITS - 1:0] wr_burst_len, // to external memory controller,data length of the burst write request, not bytes
output reg[ADDR_BITS - 1:0] wr_burst_addr, // to external memory controller,base address of the burst write request
input wr_burst_finish, // from external memory controller,burst write finish
input write_req, // data write module write request,keep '1' until read_req_ack = '1'
output reg write_req_ack, // data write module write request response
//output write_finish, // data write module write request finish
input[ADDR_BITS - 1:0] write_addr_0, // data write module write request base address 0, used when write_addr_index = 0
input[ADDR_BITS - 1:0] write_addr_1, // data write module write request base address 1, used when write_addr_index = 1
input[ADDR_BITS - 1:0] write_addr_2, // data write module write request base address 1, used when write_addr_index = 2
input[ADDR_BITS - 1:0] write_addr_3, // data write module write request base address 1, used when write_addr_index = 3
input write_addr_index, // select valid base address from write_addr_0 write_addr_1
input[ADDR_BITS - 1:0] write_len, // data write module write request data length
output reg fifo_aclr, // to fifo asynchronous clear
input[15:0] rdusedw, // from fifo read used words
input data_process_flag,
//output reg[0:0] flag_ready,
output reg ignite_cam_ready,
output reg CAM_IRQ
);
localparam ONE = 256'd1;
//256 bit '1' you can use ONE[n-1:0] for n bit '1'
localparam ZERO = 256'd0; //256 bit '0'
//write state machine code
localparam S_IDLE = 0; //idle state,waiting for write
localparam S_ACK = 1; //written request response
localparam S_CHECK_FIFO = 2; //check the FIFO status, ensure that there is enough space to burst write
localparam S_WRITE_BURST = 3; //begin a burst write
localparam S_WRITE_BURST_END = 4; //a burst write complete
localparam S_END1 = 5; //a frame of data is written to complete
localparam S_END2 = 6;
localparam S_END3 = 7;
localparam S_END4 = 8;
reg write_req_d0; //asynchronous write request, synchronize to 'mem_clk' clock domain,first beat
reg write_req_d1; //the second
reg write_req_d2; //third,Why do you need 3 ? Here's the design habit
reg[ADDR_BITS - 1:0] write_len_d0; //asynchronous write_len(write data length), synchronize to 'mem_clk' clock domain first
reg[ADDR_BITS - 1:0] write_len_d1; //second
reg[ADDR_BITS - 1:0] write_len_latch; //lock write data length
reg[ADDR_BITS - 1:0] write_cnt; //write data counter
reg write_addr_index_d0;
reg write_addr_index_d1;
reg[3:0] state; //state machine
reg[3:0] tag_state; //tag_state machine
//assign write_finish = (state == S_END) ? 1'b1 : 1'b0; //write finish at state 'S_END'
always@(posedge mem_clk or posedge rst)
begin
if(rst == 1'b1)
begin
write_req_d0 <= 1'b0;
write_req_d1 <= 1'b0;
write_req_d2 <= 1'b0;
write_len_d0 <= ZERO[ADDR_BITS - 1:0]; //equivalent to write_len_d0 <= 0;
write_len_d1 <= ZERO[ADDR_BITS - 1:0]; //equivalent to write_len_d1 <= 0;
write_addr_index_d0 <= 1'b0;
write_addr_index_d1 <= 1'b0;
end
else
begin
write_req_d0 <= write_req;
write_req_d1 <= write_req_d0;
write_req_d2 <= write_req_d1;
write_len_d0 <= write_len;
write_len_d1 <= write_len_d0;
write_addr_index_d0 <= write_addr_index;
write_addr_index_d1 <= write_addr_index_d0;
end
end
always@(posedge mem_clk or posedge rst)
begin
if(rst == 1'b1)
begin
state <= S_IDLE;
write_len_latch <= ZERO[ADDR_BITS - 1:0];
wr_burst_addr <= ZERO[ADDR_BITS - 1:0];
wr_burst_req <= 1'b0;
write_cnt <= ZERO[ADDR_BITS - 1:0];
fifo_aclr <= 1'b0;
write_req_ack <= 1'b0;
wr_burst_len <= ZERO[BUSRT_BITS - 1:0];
//flag_ready <= 1'b0;
ignite_cam_ready <= 1'b0;
CAM_IRQ <= 1'b0;
end
else
begin
case(state)
//idle state,waiting for write write_req_d2 == '1' goto the 'S_ACK'
S_IDLE:
begin
if((write_req_d2 == 1'b1) && (data_process_flag == 1'b1))
begin
state <= S_ACK;
ignite_cam_ready <= 1'b1;
end
write_req_ack <= 1'b0;
CAM_IRQ <= 1'b0;
end
//'S_ACK' state completes the write request response, the FIFO reset, the address latch, and the data length latch
S_ACK:
begin
//after write request revocation(write_req_d2 == '0'),goto 'S_CHECK_FIFO',write_req_ack goto '0'
if(write_req_d2 == 1'b0)
begin
state <= S_CHECK_FIFO;
fifo_aclr <= 1'b0;
write_req_ack <= 1'b0;
//ignite_cam_ready <= 1'b0;
end
else
begin
//write request response
write_req_ack <= 1'b1;
//FIFO reset
fifo_aclr <= 1'b1;
//set write burst address
//select valid base address from write_addr_0 write_addr_1 write_addr_2 write_addr_3
if(write_addr_index_d1 == 1'd0)
wr_burst_addr <= write_addr_0;
else if(write_addr_index_d1 == 1'd1)
wr_burst_addr <= write_addr_1;
//latch data length
write_len_latch <= write_len_d1;
end
//write data counter reset, write_cnt <= 0;
write_cnt <= ZERO[ADDR_BITS - 1:0];
end
S_CHECK_FIFO:
begin
ignite_cam_ready <= 1'b0;
//if there is a write request at this time, enter the 'S_ACK' state
if(write_req_d2 == 1'b1)
begin
state <= S_ACK;
end
//if the FIFO space is a burst write request, goto burst write state
else if(rdusedw >= BURST_SIZE)
begin
state <= S_WRITE_BURST;
wr_burst_len <= BURST_SIZE[BUSRT_BITS - 1:0];
wr_burst_req <= 1'b1;
end
end
S_WRITE_BURST:
begin
//burst finish
if(wr_burst_finish == 1'b1)
begin
wr_burst_req <= 1'b0;
state <= S_WRITE_BURST_END;
//write counter + burst length
write_cnt <= write_cnt + BURST_SIZE[ADDR_BITS - 1:0];
//the next burst write address is generated
wr_burst_addr <= wr_burst_addr + BURST_SIZE[ADDR_BITS - 1:0];
end
end
S_WRITE_BURST_END:
begin
//if there is a write request at this time, enter the 'S_ACK' state
if(write_req_d2 == 1'b1)
begin
state <= S_ACK;
end
//if the write counter value is less than the frame length, continue writing,
//otherwise the writing is complete
else if(write_cnt < write_len_latch)
begin
state <= S_CHECK_FIFO;
end
else
begin
state <= S_END1;
CAM_IRQ <= 1'b1;
end
end
S_END1:
begin
state <= S_END2;
end
S_END2:
begin
state <= S_END3;
end
S_END3:
begin
state <= S_END4;
end
S_END4:
begin
state <= S_IDLE;
end
// S_END:
// begin
// state <= T_ACK;
// flag_ready <= 1'b1;
// end
// T_ACK:
// begin
// state <= T_WRITE_BURST;
// wr_burst_addr <= write_addr_3;
// wr_burst_len <= ONE[BUSRT_BITS - 1:0];
// wr_burst_req <= 1'b1;
// end
// T_WRITE_BURST:
// begin
// //burst finish
// if(wr_burst_finish == 1'b1)
// begin
// wr_burst_req <= 1'b0;
// state <= T_END;
// end
// end
// T_END:
// begin
// flag_ready <= 1'b0;
// state <= S_IDLE;
// end
default:
state <= S_IDLE;
endcase
end
end
endmodule

View File

@ -0,0 +1,153 @@
`timescale 1ns/1ps
module frame_read_write_cam
#
(
parameter MEM_DATA_BITS = 32,
parameter READ_DATA_BITS = 16,
parameter WRITE_DATA_BITS = 16,
parameter ADDR_BITS = 28,
parameter BUSRT_BITS = 10,
parameter BURST_SIZE = 128
)
(
input rst,
input mem_clk, // external memory controller user interface clock
input data_process_flag,
output wire ignite_cam_ready,
output wire CAM_IRQ,
output rd_burst_req, // to external memory controller,send out a burst read request
output[BUSRT_BITS - 1:0] rd_burst_len, // to external memory controller,data length of the burst read request, not bytes
output[ADDR_BITS - 1:0] rd_burst_addr, // to external memory controller,base address of the burst read request
input rd_burst_data_valid, // from external memory controller,read data valid
input[MEM_DATA_BITS - 1:0] rd_burst_data, // from external memory controller,read request data
input rd_burst_finish, // from external memory controller,burst read finish
input read_clk, // data read module clock
input read_req, // data read module read request,keep '1' until read_req_ack = '1'
output read_req_ack, // data read module read request response
output read_finish, // data read module read request finish
input[ADDR_BITS - 1:0] read_addr_0, // data read module read request base address 0, used when read_addr_index = 0
input[ADDR_BITS - 1:0] read_addr_1, // data read module read request base address 1, used when read_addr_index = 1
input[ADDR_BITS - 1:0] read_addr_2, // data read module read request base address 1, used when read_addr_index = 2
input[ADDR_BITS - 1:0] read_addr_3, // data read module read request base address 1, used when read_addr_index = 3
input read_addr_index, // select valid base address from read_addr_0 read_addr_1
input[ADDR_BITS - 1:0] read_len, // data read module read request data length
input read_en, // data read module read request for one data, read_data valid next clock
output[READ_DATA_BITS - 1:0] read_data, // read data
output wr_burst_req, // to external memory controller,send out a burst write request
output[BUSRT_BITS - 1:0] wr_burst_len, // to external memory controller,data length of the burst write request, not bytes
output[ADDR_BITS - 1:0] wr_burst_addr, // to external memory controller,base address of the burst write request
input wr_burst_data_req, // from external memory controller,write data request ,before data 1 clock
output[MEM_DATA_BITS - 1:0] wr_burst_data, // to external memory controller,write data
input wr_burst_finish, // from external memory controller,burst write finish
input write_clk, // data write module clock
input write_req, // data write module write request,keep '1' until read_req_ack = '1'
output write_req_ack, // data write module write request response
input[ADDR_BITS - 1:0] write_addr_0, // data write module write request base address 0, used when write_addr_index = 0
input[ADDR_BITS - 1:0] write_addr_1, // data write module write request base address 1, used when write_addr_index = 1
input[ADDR_BITS - 1:0] write_addr_2, // data write module write request base address 1, used when write_addr_index = 2
input[ADDR_BITS - 1:0] write_addr_3, // data write module write request base address 1, used when write_addr_index = 3
input write_addr_index, // select valid base address from write_addr_0 write_addr_1
input[ADDR_BITS - 1:0] write_len, // data write module write request data length
input write_en, // data write module write request for one data
input[WRITE_DATA_BITS - 1:0] write_data // write data
);
wire[15:0] wrusedw; // write used words
wire[15:0] rdusedw; // read used words
wire read_fifo_aclr; // fifo Asynchronous clear
wire write_fifo_aclr; // fifo Asynchronous clear
//instantiate an asynchronous FIFO
afifo_16i_32o_512 write_buf (
.rst (write_fifo_aclr ),
.wr_clk (write_clk ),
.rd_clk (mem_clk ),
.din (write_data ),
.wr_en (write_en ),
.rd_en (wr_burst_data_req ),
.dout (wr_burst_data ),
.full ( ),
.empty ( ),
.rd_data_count (rdusedw ), // number of data used seen from the FIFO read side
.wr_data_count ( )
);
frame_fifo_write_cam
#
(
.MEM_DATA_BITS (MEM_DATA_BITS ), //32
.ADDR_BITS (ADDR_BITS ), //28
.BUSRT_BITS (BUSRT_BITS ), //10
.BURST_SIZE (BURST_SIZE ) //128
)
frame_fifo_write_cam_m0
(
.rst (rst ),
.mem_clk (mem_clk ),
.wr_burst_req (wr_burst_req ),
.wr_burst_len (wr_burst_len ),
.wr_burst_addr (wr_burst_addr ),
.wr_burst_finish (wr_burst_finish ),
.write_req (write_req ),
.write_req_ack (write_req_ack ),
.write_addr_0 (write_addr_0 ),
.write_addr_1 (write_addr_1 ),
.write_addr_2 (write_addr_2 ),
.write_addr_3 (write_addr_3 ),
.write_addr_index (write_addr_index ),
.write_len (write_len ),
.fifo_aclr (write_fifo_aclr ),
.rdusedw (rdusedw ),
.data_process_flag (data_process_flag ),
.ignite_cam_ready (ignite_cam_ready ),
.CAM_IRQ (CAM_IRQ )
);
//instantiate an asynchronous FIFO
afifo_32i_16o_256 read_buf (
.rst (read_fifo_aclr ),
.wr_clk (mem_clk ),
.rd_clk (read_clk ),
.din (rd_burst_data ),
.wr_en (rd_burst_data_valid ),
.rd_en (read_en ),
.dout (read_data ),
.full ( ),
.empty ( ),
.rd_data_count ( ),
.wr_data_count (wrusedw )
);
frame_fifo_read_cam
#
(
.MEM_DATA_BITS (MEM_DATA_BITS ),
.ADDR_BITS (ADDR_BITS ),
.BUSRT_BITS (BUSRT_BITS ),
.FIFO_DEPTH (256 ),
.BURST_SIZE (BURST_SIZE )
)
frame_fifo_read_cam_m0
(
.rst (rst ),
.mem_clk (mem_clk ),
.rd_burst_req (rd_burst_req ),
.rd_burst_len (rd_burst_len ),
.rd_burst_addr (rd_burst_addr ),
.rd_burst_data_valid (rd_burst_data_valid ),
.rd_burst_finish (rd_burst_finish ),
.read_req (read_req ),
.read_req_ack (read_req_ack ),
.read_finish (read_finish ),
.read_addr_0 (read_addr_0 ),
.read_addr_1 (read_addr_1 ),
.read_addr_2 (read_addr_2 ),
.read_addr_3 (read_addr_3 ),
.read_addr_index (read_addr_index ),
.read_len (read_len ),
.fifo_aclr (read_fifo_aclr ),
.wrusedw (wrusedw )
);
endmodule

View File

@ -0,0 +1,129 @@
module i2c_config(
input rst,
input clk,
input[15:0] clk_div_cnt,
input i2c_addr_2byte,
output reg[9:0] lut_index,
input[7:0] lut_dev_addr,
input[15:0] lut_reg_addr,
input[7:0] lut_reg_data,
output reg error,
output done,
inout i2c_scl,
inout i2c_sda
);
wire scl_pad_i;
wire scl_pad_o;
wire scl_padoen_o;
wire sda_pad_i;
wire sda_pad_o;
wire sda_padoen_o;
assign sda_pad_i = i2c_sda;
assign i2c_sda = ~sda_padoen_o ? sda_pad_o : 1'bz;
assign scl_pad_i = i2c_scl;
assign i2c_scl = ~scl_padoen_o ? scl_pad_o : 1'bz;
reg i2c_read_req;
wire i2c_read_req_ack;
reg i2c_write_req;
wire i2c_write_req_ack;
wire[7:0] i2c_slave_dev_addr;
wire[15:0] i2c_slave_reg_addr;
wire[7:0] i2c_write_data;
wire[7:0] i2c_read_data;
wire err;
reg[2:0] state;
localparam S_IDLE = 0;
localparam S_WR_I2C_CHECK = 1;
localparam S_WR_I2C = 2;
localparam S_WR_I2C_DONE = 3;
assign done = (state == S_WR_I2C_DONE);
assign i2c_slave_dev_addr = lut_dev_addr;
assign i2c_slave_reg_addr = lut_reg_addr;
assign i2c_write_data = lut_reg_data;
always@(posedge clk or posedge rst)
begin
if(rst)
begin
state <= S_IDLE;
error <= 1'b0;
lut_index <= 8'd0;
end
else
case(state)
S_IDLE:
begin
state <= S_WR_I2C_CHECK;
error <= 1'b0;
lut_index <= 8'd0;
end
S_WR_I2C_CHECK:
begin
if(i2c_slave_dev_addr != 8'hff)
begin
i2c_write_req <= 1'b1;
state <= S_WR_I2C;
end
else
begin
state <= S_WR_I2C_DONE;
end
end
S_WR_I2C:
begin
if(i2c_write_req_ack)
begin
error <= err ? 1'b1 : error;
lut_index <= lut_index + 8'd1;
i2c_write_req <= 1'b0;
state <= S_WR_I2C_CHECK;
end
end
S_WR_I2C_DONE:
begin
state <= S_WR_I2C_DONE;
end
default:
state <= S_IDLE;
endcase
end
i2c_master_top i2c_master_top_m0
(
.rst(rst),
.clk(clk),
.clk_div_cnt(clk_div_cnt),
// I2C signals
// i2c clock line
.scl_pad_i(scl_pad_i), // SCL-line input
.scl_pad_o(scl_pad_o), // SCL-line output (always 1'b0)
.scl_padoen_o(scl_padoen_o), // SCL-line output enable (active low)
// i2c data line
.sda_pad_i(sda_pad_i), // SDA-line input
.sda_pad_o(sda_pad_o), // SDA-line output (always 1'b0)
.sda_padoen_o(sda_padoen_o), // SDA-line output enable (active low)
.i2c_read_req(i2c_read_req),
.i2c_addr_2byte(i2c_addr_2byte),
.i2c_read_req_ack(i2c_read_req_ack),
.i2c_write_req(i2c_write_req),
.i2c_write_req_ack(i2c_write_req_ack),
.i2c_slave_dev_addr(i2c_slave_dev_addr),
.i2c_slave_reg_addr(i2c_slave_reg_addr),
.i2c_write_data(i2c_write_data),
.i2c_read_data(i2c_read_data),
.error(err)
);
endmodule

View File

@ -0,0 +1,620 @@
/////////////////////////////////////////////////////////////////////
//// ////
//// WISHBONE rev.B2 compliant I2C Master bit-controller ////
//// ////
//// ////
//// Author: Richard Herveille ////
//// richard@asics.ws ////
//// www.asics.ws ////
//// ////
//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2001 Richard Herveille ////
//// richard@asics.ws ////
//// ////
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
//// POSSIBILITY OF SUCH DAMAGE. ////
//// ////
/////////////////////////////////////////////////////////////////////
// CVS Log
//
// $Id: i2c_master_bit_ctrl.v,v 1.14 2009-01-20 10:25:29 rherveille Exp $
//
// $Date: 2009-01-20 10:25:29 $
// $Revision: 1.14 $
// $Author: rherveille $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: $
// Revision 1.14 2009/01/20 10:25:29 rherveille
// Added clock synchronization logic
// Fixed slave_wait signal
//
// Revision 1.13 2009/01/19 20:29:26 rherveille
// Fixed synopsys miss spell (synopsis)
// Fixed cr[0] register width
// Fixed ! usage instead of ~
// Fixed bit controller parameter width to 18bits
//
// Revision 1.12 2006/09/04 09:08:13 rherveille
// fixed short scl high pulse after clock stretch
// fixed slave model not returning correct '(n)ack' signal
//
// Revision 1.11 2004/05/07 11:02:26 rherveille
// Fixed a bug where the core would signal an arbitration lost (AL bit set), when another master controls the bus and the other master generates a STOP bit.
//
// Revision 1.10 2003/08/09 07:01:33 rherveille
// Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
// Fixed a potential bug in the byte controller's host-acknowledge generation.
//
// Revision 1.9 2003/03/10 14:26:37 rherveille
// Fixed cmd_ack generation item (no bug).
//
// Revision 1.8 2003/02/05 00:06:10 rherveille
// Fixed a bug where the core would trigger an erroneous 'arbitration lost' interrupt after being reset, when the reset pulse width < 3 clk cycles.
//
// Revision 1.7 2002/12/26 16:05:12 rherveille
// Small code simplifications
//
// Revision 1.6 2002/12/26 15:02:32 rherveille
// Core is now a Multimaster I2C controller
//
// Revision 1.5 2002/11/30 22:24:40 rherveille
// Cleaned up code
//
// Revision 1.4 2002/10/30 18:10:07 rherveille
// Fixed some reported minor start/stop generation timing issuess.
//
// Revision 1.3 2002/06/15 07:37:03 rherveille
// Fixed a small timing bug in the bit controller.\nAdded verilog simulation environment.
//
// Revision 1.2 2001/11/05 11:59:25 rherveille
// Fixed wb_ack_o generation bug.
// Fixed bug in the byte_controller statemachine.
// Added headers.
//
//
/////////////////////////////////////
// Bit controller section
/////////////////////////////////////
//
// Translate simple commands into SCL/SDA transitions
// Each command has 5 states, A/B/C/D/idle
//
// start: SCL ~~~~~~~~~~\____
// SDA ~~~~~~~~\______
// x | A | B | C | D | i
//
// repstart SCL ____/~~~~\___
// SDA __/~~~\______
// x | A | B | C | D | i
//
// stop SCL ____/~~~~~~~~
// SDA ==\____/~~~~~
// x | A | B | C | D | i
//
//- write SCL ____/~~~~\____
// SDA ==X=========X=
// x | A | B | C | D | i
//
//- read SCL ____/~~~~\____
// SDA XXXX=====XXXX
// x | A | B | C | D | i
//
// Timing: Normal mode Fast mode
///////////////////////////////////////////////////////////////////////
// Fscl 100KHz 400KHz
// Th_scl 4.0us 0.6us High period of SCL
// Tl_scl 4.7us 1.3us Low period of SCL
// Tsu:sta 4.7us 0.6us setup time for a repeated start condition
// Tsu:sto 4.0us 0.6us setup time for a stop conditon
// Tbuf 4.7us 1.3us Bus free time between a stop and start condition
//
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "i2c_master_defines.v"
module i2c_master_bit_ctrl (
input clk, //system clock
input rst, //synchronous active high reset
input nReset, //asynchronous active low reset
input ena, //core enable signal
input [15:0] clk_cnt, //clock prescale value
input [ 3:0] cmd, //command (from byte controller)
output reg cmd_ack, //command complete acknowledge
output reg busy, //i2c bus busy
output reg al, //i2c bus arbitration lost
input din,
output reg dout,
input scl_i, //i2c clock line input
output scl_o, //i2c clock line output
output reg scl_oen, //i2c clock line output enable (active low)
input sda_i, //i2c data line input
output sda_o, //i2c data line output
output reg sda_oen //i2c data line output enable (active low)
);
//
// variable declarations
//
reg [1:0] cSCL,cSDA; //capture SCL and SDA
reg [2:0] fSCL,fSDA; //SCL and SDA filter inputs
reg sSCL,sSDA; //filtered and synchronized SCL and SDA inputs
reg dSCL,dSDA; //delayed versions of sSCL and sSDA
reg dscl_oen; //delayed scl_oen
reg sda_chk; //check SDA output (Multi-master arbitration)
reg clk_en; //clock generation signals(LOW active)
reg slave_wait; //slave inserts wait states
reg [15:0]cnt; //clock divider counter (synthesis)
reg [13:0]filter_cnt; //clock divider for filter
// state machine variable
reg [17:0] c_state; // synopsys enum_state
//
// module body
//
// whenever the slave is not ready it can delay the cycle by pulling SCL low
// delay scl_oen
always @(posedge clk)
dscl_oen <= #1 scl_oen;
// slave_wait is asserted when master wants to drive SCL high, but the slave pulls it low
// slave_wait remains asserted until the slave releases SCL
always @(posedge clk or negedge nReset)
begin
if(!nReset)
slave_wait <= 1'b0;
else
slave_wait <= (scl_oen & ~dscl_oen & ~sSCL)|(slave_wait & ~sSCL);
end
// master drives SCL high, but another master pulls it low
// master start counting down its low cycle now (clock synchronization)
wire scl_sync = dSCL&~sSCL&scl_oen;
// generate clk enable signal
always @(posedge clk or negedge nReset)
begin
if (!nReset)
begin
cnt <= #1 16'h0;
clk_en <= #1 1'b1;
end
else if (rst || ~(|cnt) || (!ena) || scl_sync)
begin
cnt <= #1 clk_cnt;
clk_en <= #1 1'b1;
end
else if (slave_wait)
begin
cnt <= #1 cnt;
clk_en <= #1 1'b0;
end
else
begin
cnt <= #1 cnt-16'h1;
clk_en <= #1 1'b0;
end
end
// generate bus status controller
// capture SDA and SCL
// reduce metastability risk
always @(posedge clk or negedge nReset)
begin
if (!nReset)
begin
cSCL <= #1 2'b00;
cSDA <= #1 2'b00;
end
else if (rst)
begin
cSCL <= #1 2'b00;
cSDA <= #1 2'b00;
end
else
begin
cSCL <= {cSCL[0],scl_i};
cSDA <= {cSDA[0],sda_i};
end
end
/*usually use this mode take some operation
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
cscl<=2'b00;
csda<=2'b00;
else
cscl<={cscl[max:0],scl_i};
csda<={csda[max:0],sda_i};//cache the input signal
end
assign post_cscl_en=cscl[max-1]&~cscl[max];//negedge
assign post_csda=csda[max+1];//delay (max+1) clock period
*/
// filter SCL and SDA signals; (attempt to) remove glitches
always @(posedge clk or negedge nReset)
begin
if(!nReset)
filter_cnt <= 14'h0;
else if (rst || !ena )
filter_cnt <= 14'h0;
else if (~|filter_cnt)
filter_cnt <= clk_cnt >> 2; //16x I2C bus frequency(4*fSCL)
else
filter_cnt <= filter_cnt -1;
end
always @(posedge clk or negedge nReset)//fSCL is the Operation control clock
begin
if(!nReset)
begin
fSCL <= 3'b111;
fSDA <= 3'b111;
end
else if (rst)
begin
fSCL <= 3'b111;
fSDA <= 3'b111;
end
else if (~|filter_cnt)
begin
fSCL <= {fSCL[1:0],cSCL[1]};
fSDA <= {fSDA[1:0],cSDA[1]};
end
end
// generate filtered SCL and SDA signals
always @(posedge clk or negedge nReset)
begin
if (~nReset)
begin
sSCL <= #1 1'b1;
sSDA <= #1 1'b1;
dSCL <= #1 1'b1;
dSDA <= #1 1'b1;
end
else if (rst)
begin
sSCL <= #1 1'b1;
sSDA <= #1 1'b1;
dSCL <= #1 1'b1;
dSDA <= #1 1'b1;
end
else
begin
sSCL <= #1 &fSCL[2:1] | &fSCL[1:0] | (fSCL[2] & fSCL[0]);
sSDA <= #1 &fSDA[2:1] | &fSDA[1:0] | (fSDA[2] & fSDA[0]);
dSCL <= #1 sSCL;
dSDA <= #1 sSDA;
end
end
// detect start condition => detect falling edge on SDA while SCL is high
// detect stop condition => detect rising edge on SDA while SCL is high
reg sta_condition;
reg sto_condition;
always @(posedge clk or negedge nReset)
begin
if(~nReset)
begin
sta_condition <= #1 1'b0;
sto_condition <= #1 1'b0;
end
else if (rst)
begin
sta_condition <= #1 1'b0;
sto_condition <= #1 1'b0;
end
else
begin
sta_condition <= #1 ~sSDA & dSDA & sSCL;//falling edge,start signal
sto_condition <= #1 sSDA & ~dSDA & sSCL;//rising edge,stop signal
end
end
// generate i2c bus busy signal
always @(posedge clk or negedge nReset)
begin
if(!nReset)
busy <= #1 1'b0;
else if (rst)
busy <= #1 1'b0;
else
busy <= #1 (sta_condition | busy) & ~sto_condition;
end
// generate arbitration lost signal+
// aribitration lost when:
// 1) master drives SDA high, but the i2c bus is low
// 2) stop detected while not requested
reg cmd_stop;
always @(posedge clk or negedge nReset)
begin
if(~nReset)
cmd_stop <= #1 1'b0;
else if(rst)
cmd_stop <= #1 1'b0;
else if(clk_en)
cmd_stop <= #1 cmd == `I2C_CMD_STOP;
end
always @(posedge clk or negedge nReset) //仲裁丢失当检测到停止信号没有检测到请求信号主机设置SDA为高电平但实际上SDA为低电平
begin
if(~nReset)
al <= #1 1'b0;
else if(rst)
al <= #1 1'b0;
else
al <= #1 (sda_chk & ~sSDA & sda_oen)|(|c_state & sto_condition & ~cmd_stop);
end
// generate dout signal (store SDA on rising edge of SCL)
always @(posedge clk)
if(sSCL & ~dSCL)
dout <= #1 sSDA;
// generate statemachine
// nxt_state decoder
parameter [17:0] idle = 18'b0_0000_0000_0000_0000;
parameter [17:0] start_a= 18'b0_0000_0000_0000_0001;
parameter [17:0] start_b= 18'b0_0000_0000_0000_0010;
parameter [17:0] start_c= 18'b0_0000_0000_0000_0100;
parameter [17:0] start_d= 18'b0_0000_0000_0000_1000;
parameter [17:0] start_e= 18'b0_0000_0000_0001_0000;
parameter [17:0] stop_a = 18'b0_0000_0000_0010_0000;
parameter [17:0] stop_b = 18'b0_0000_0000_0100_0000;
parameter [17:0] stop_c = 18'b0_0000_0000_1000_0000;
parameter [17:0] stop_d = 18'b0_0000_0001_0000_0000;
parameter [17:0] rd_a = 18'b0_0000_0010_0000_0000;
parameter [17:0] rd_b = 18'b0_0000_0100_0000_0000;
parameter [17:0] rd_c = 18'b0_0000_1000_0000_0000;
parameter [17:0] rd_d = 18'b0_0001_0000_0000_0000;
parameter [17:0] wr_a = 18'b0_0010_0000_0000_0000;
parameter [17:0] wr_b = 18'b0_0100_0000_0000_0000;
parameter [17:0] wr_c = 18'b0_1000_0000_0000_0000;
parameter [17:0] wr_d = 18'b1_0000_0000_0000_0000;
always @(posedge clk or negedge nReset)
begin
if(!nReset)
begin
c_state <= #1 idle;
cmd_ack <= #1 1'b0;
scl_oen <= #1 1'b1;
sda_oen <= #1 1'b1;
sda_chk <= #1 1'b0;
end
else if (rst | al)
begin
c_state <= #1 idle;
cmd_ack <= #1 1'b0;
scl_oen <= #1 1'b1;
sda_oen <= #1 1'b1;
sda_chk <= #1 1'b0;
end
else
begin
cmd_ack <= #1 1'b0; //default no command acknowledge + assert cmd_ack only 1 clk cycle
if(clk_en)
case (c_state) //synopsys full_case parallel_case
// idle state
idle:
begin
case (cmd) //synopsys full_case parallel_case
`I2C_CMD_START: c_state <= #1 start_a;
`I2C_CMD_STOP: c_state <= #1 stop_a;
`I2C_CMD_WRITE: c_state <= #1 wr_a;
`I2C_CMD_READ: c_state <= #1 rd_a;
default: c_state <= #1 idle;
endcase
scl_oen <= #1 scl_oen; // keep SCL in same state
sda_oen <= #1 sda_oen; // keep SDA in same state
sda_chk <= #1 1'b0; // don't check SDA output
end
// start
start_a:
begin
c_state <= #1 start_b;
scl_oen <= #1 scl_oen; // keep SCL in same state
sda_oen <= #1 1'b1; // set SDA high
sda_chk <= #1 1'b0; // don't check SDA output
end
start_b:
begin
c_state <= #1 start_c;
scl_oen <= #1 1'b1; // set SCL high
sda_oen <= #1 1'b1; // keep SDA high
sda_chk <= #1 1'b0; // don't check SDA output
end
start_c:
begin
c_state <= #1 start_d;
scl_oen <= #1 1'b1; // keep SCL high
sda_oen <= #1 1'b0; // set SDA low
sda_chk <= #1 1'b0; // don't check SDA output
end
start_d:
begin
c_state <= #1 start_e;
scl_oen <= #1 1'b1; // keep SCL high
sda_oen <= #1 1'b0; // keep SDA low
sda_chk <= #1 1'b0; // don't check SDA output
end
start_e:
begin
c_state <= #1 idle;
cmd_ack <= #1 1'b1;
scl_oen <= #1 1'b0; // set SCL low
sda_oen <= #1 1'b0; // keep SDA low
sda_chk <= #1 1'b0; // don't check SDA output
end
// stop
stop_a:
begin
c_state <= #1 stop_b;
scl_oen <= #1 1'b0; // keep SCL low
sda_oen <= #1 1'b0; // set SDA low
sda_chk <= #1 1'b0; // don't check SDA output
end
stop_b:
begin
c_state <= #1 stop_c;
scl_oen <= #1 1'b1; // set SCL high
sda_oen <= #1 1'b0; // keep SDA low
sda_chk <= #1 1'b0; // don't check SDA output
end
stop_c:
begin
c_state <= #1 stop_d;
scl_oen <= #1 1'b1; // keep SCL high
sda_oen <= #1 1'b0; // keep SDA low
sda_chk <= #1 1'b0; // don't check SDA output
end
stop_d:
begin
c_state <= #1 idle;
cmd_ack <= #1 1'b1;
scl_oen <= #1 1'b1; // keep SCL high
sda_oen <= #1 1'b1; // set SDA high
sda_chk <= #1 1'b0; // don't check SDA output
end
// read
rd_a:
begin
c_state <= #1 rd_b;
scl_oen <= #1 1'b0; // keep SCL low
sda_oen <= #1 1'b1; // tri-state SDA
sda_chk <= #1 1'b0; // don't check SDA output
end
rd_b:
begin
c_state <= #1 rd_c;
scl_oen <= #1 1'b1; // set SCL high
sda_oen <= #1 1'b1; // keep SDA tri-stated
sda_chk <= #1 1'b0; // don't check SDA output
end
rd_c:
begin
c_state <= #1 rd_d;
scl_oen <= #1 1'b1; // keep SCL high
sda_oen <= #1 1'b1; // keep SDA tri-stated
sda_chk <= #1 1'b0; // don't check SDA output
end
rd_d:
begin
c_state <= #1 idle;
cmd_ack <= #1 1'b1;
scl_oen <= #1 1'b0; // set SCL low
sda_oen <= #1 1'b1; // keep SDA tri-stated
sda_chk <= #1 1'b0; // don't check SDA output
end
// write
wr_a:
begin
c_state <= #1 wr_b;
scl_oen <= #1 1'b0; // keep SCL low
sda_oen <= #1 din; // set SDA
sda_chk <= #1 1'b0; // don't check SDA output (SCL low)
end
wr_b:
begin
c_state <= #1 wr_c;
scl_oen <= #1 1'b1; // set SCL high
sda_oen <= #1 din; // keep SDA
sda_chk <= #1 1'b0; // don't check SDA output yet
// allow some time for SDA and SCL to settle
end
wr_c:
begin
c_state <= #1 wr_d;
scl_oen <= #1 1'b1; // keep SCL high
sda_oen <= #1 din;
sda_chk <= #1 1'b1; // check SDA output
end
wr_d:
begin
c_state <= #1 idle;
cmd_ack <= #1 1'b1;
scl_oen <= #1 1'b0; // set SCL low
sda_oen <= #1 din;
sda_chk <= #1 1'b0; // don't check SDA output (SCL low)
end
endcase
end
end
// assign scl and sda output (always gnd)
assign scl_o = 1'b0;
assign sda_o = 1'b0;
endmodule

View File

@ -0,0 +1,350 @@
/////////////////////////////////////////////////////////////////////
//// ////
//// WISHBONE rev.B2 compliant I2C Master byte-controller ////
//// ////
//// ////
//// Author: Richard Herveille ////
//// richard@asics.ws ////
//// www.asics.ws ////
//// ////
//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2001 Richard Herveille ////
//// richard@asics.ws ////
//// ////
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
//// POSSIBILITY OF SUCH DAMAGE. ////
//// ////
/////////////////////////////////////////////////////////////////////
// CVS Log
//
// $Id: i2c_master_byte_ctrl.v,v 1.8 2009-01-19 20:29:26 rherveille Exp $
//
// $Date: 2009-01-19 20:29:26 $
// $Revision: 1.8 $
// $Author: rherveille $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: not supported by cvs2svn $
// Revision 1.7 2004/02/18 11:40:46 rherveille
// Fixed a potential bug in the statemachine. During a 'stop' 2 cmd_ack signals were generated. Possibly canceling a new start command.
//
// Revision 1.6 2003/08/09 07:01:33 rherveille
// Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
// Fixed a potential bug in the byte controller's host-acknowledge generation.
//
// Revision 1.5 2002/12/26 15:02:32 rherveille
// Core is now a Multimaster I2C controller
//
// Revision 1.4 2002/11/30 22:24:40 rherveille
// Cleaned up code
//
// Revision 1.3 2001/11/05 11:59:25 rherveille
// Fixed wb_ack_o generation bug.
// Fixed bug in the byte_controller statemachine.
// Added headers.
//
// synopsys translate_off
`include "timescale.v"
// synopsys translate_on
`include "i2c_master_defines.v"
module i2c_master_byte_ctrl
(
clk,rst,nReset,ena,
clk_cnt,start,stop,
read, write, ack_in,
din,cmd_ack,ack_out,
dout,i2c_busy,i2c_al,
scl_i,scl_o,scl_oen,
sda_i,sda_o, sda_oen
);
//
// inputs & outputs
//
input clk; // master clock
input rst; // synchronous active high reset(Global reset signal)
input nReset; // asynchronous active low reset
input ena; // core enable signal
input [15:0]clk_cnt; // 4x SCL
// control inputs
input start;
input stop;
input read;
input write;
input ack_in;
input [7:0] din;
// status outputs
output reg cmd_ack;
//reg cmd_ack;
output reg ack_out;
//reg ack_out;
output i2c_busy;
output i2c_al;
output [7:0]dout;
// I2C signals
input scl_i;
output scl_o;
output scl_oen;
input sda_i;
output sda_o;
output sda_oen;
// Variable declarations
// statemachine
parameter [4:0] ST_IDLE = 5'b0_0000;
parameter [4:0] ST_START = 5'b0_0001;
parameter [4:0] ST_READ = 5'b0_0010;
parameter [4:0] ST_WRITE = 5'b0_0100;
parameter [4:0] ST_ACK = 5'b0_1000;
parameter [4:0] ST_STOP = 5'b1_0000;
// signals for bit_controller
reg [3:0]core_cmd;
reg core_txd;
wire core_ack, core_rxd;
// signals for shift register
reg [7:0]sr; //8bit shift register
reg shift, ld;
// signals for state machine
wire go;
reg [2:0]dcnt;
wire cnt_done;
// Module body
// hookup bit_controller
i2c_master_bit_ctrl bit_controller
(
.clk ( clk ),
.rst ( rst ),
.nReset ( nReset ),
.ena ( ena ),
.clk_cnt ( clk_cnt ),
.cmd ( core_cmd ),
.cmd_ack ( core_ack ),
.busy ( i2c_busy ),
.al ( i2c_al ),
.din ( core_txd ),
.dout ( core_rxd ),
.scl_i ( scl_i ),
.scl_o ( scl_o ),
.scl_oen ( scl_oen ),
.sda_i ( sda_i ),
.sda_o ( sda_o ),
.sda_oen ( sda_oen )
);
// generate go-signal
assign go = (read | write | stop) & ~cmd_ack; //the cmd_ack<EFBFBD><EFBFBD>? was low actived
// generate shift register
always @(posedge clk or negedge nReset)
begin
if (!nReset)
sr <= #1 8'h0; //the"#"just for modelsim,it's not used when Analysis & Synthesis
else if (rst==1)
sr <= #1 8'h0;
else if (ld) //load data
sr <= #1 din; //din is the input data
else if (shift)
sr <= #1 {sr[6:0], core_rxd};
end
// assign dout output to shift-register
assign dout = sr;
// generate counter
always @(posedge clk or negedge nReset)
begin
if (!nReset)
dcnt <= #1 3'h0;
else if (rst)
dcnt <= #1 3'h0;
else if (ld)
dcnt <= #1 3'h7;
else if (shift)
dcnt <= #1 dcnt - 3'h1;
end
assign cnt_done = ~(|dcnt); //|is Abbreviation operatorjust one operand,Operation is performed by bitwise operation from left to right
// state machine
reg [4:0] c_state; // synopsys enum_state
always @(posedge clk or negedge nReset)
if(!nReset)
begin
core_cmd <= #1 `I2C_CMD_NOP;
core_txd <= #1 1'b0;
shift <= #1 1'b0;
ld <= #1 1'b0;
cmd_ack <= #1 1'b0;
c_state <= #1 ST_IDLE;
ack_out <= #1 1'b0;
end
else if (rst | i2c_al)
begin
core_cmd <= #1 `I2C_CMD_NOP;
core_txd <= #1 1'b0;
shift <= #1 1'b0;
ld <= #1 1'b0;
cmd_ack <= #1 1'b0;
c_state <= #1 ST_IDLE;
ack_out <= #1 1'b0;
end
else
begin
// initially reset all signals
core_txd <= #1 sr[7];
shift <= #1 1'b0;
ld <= #1 1'b0;
cmd_ack <= #1 1'b0;
case (c_state) // synopsys full_case parallel_case
ST_IDLE:
if (go)
begin
if (start)
begin
c_state <= #1 ST_START;
core_cmd <= #1 `I2C_CMD_START;
end
else if (read)
begin
c_state <= #1 ST_READ;
core_cmd <= #1 `I2C_CMD_READ;
end
else if (write)
begin
c_state <= #1 ST_WRITE;
core_cmd <= #1 `I2C_CMD_WRITE;
end
else // stop
begin
c_state <= #1 ST_STOP;
core_cmd <= #1 `I2C_CMD_STOP;
end
ld <= #1 1'b1;
end
ST_START:
if (core_ack)
begin
if (read)
begin
c_state <= #1 ST_READ;
core_cmd <= #1 `I2C_CMD_READ;
end
else
begin
c_state <= #1 ST_WRITE;
core_cmd <= #1 `I2C_CMD_WRITE;
end
ld <= #1 1'b1;
end
ST_WRITE:
if (core_ack)
if (cnt_done)
begin
c_state <= #1 ST_ACK;
core_cmd <= #1 `I2C_CMD_READ;
end
else
begin
c_state <= #1 ST_WRITE; // stay in same state
core_cmd <= #1 `I2C_CMD_WRITE; // write next bit
shift <= #1 1'b1;
end
ST_READ:
if (core_ack)
begin
if (cnt_done)
begin
c_state <= #1 ST_ACK;
core_cmd <= #1 `I2C_CMD_WRITE;
end
else
begin
c_state <= #1 ST_READ; // stay in same state
core_cmd <= #1 `I2C_CMD_READ; // read next bit
end
shift <= #1 1'b1;
core_txd <= #1 ack_in;
end
ST_ACK:
if (core_ack)
begin
if (stop)
begin
c_state <= #1 ST_STOP;
core_cmd <= #1 `I2C_CMD_STOP;
end
else
begin
c_state <= #1 ST_IDLE;
core_cmd <= #1 `I2C_CMD_NOP;
//generate command acknowledge signal
cmd_ack <= #1 1'b1;
end
//assign ack_out output to bit_controller(contains last received bit)
ack_out <= #1 core_rxd;
core_txd <= #1 1'b1;
end
else
core_txd <= #1 ack_in;
ST_STOP:
if (core_ack)
begin
c_state <= #1 ST_IDLE;
core_cmd <= #1 `I2C_CMD_NOP;
// generate command acknowledge signal
cmd_ack <= #1 1'b1;
end
endcase
end
endmodule

View File

@ -0,0 +1,59 @@
/////////////////////////////////////////////////////////////////////
//// ////
//// WISHBONE rev.B2 compliant I2C Master controller defines ////
//// ////
//// ////
//// Author: Richard Herveille ////
//// richard@asics.ws ////
//// www.asics.ws ////
//// ////
//// Downloaded from: http://www.opencores.org/projects/i2c/ ////
//// ////
/////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2001 Richard Herveille ////
//// richard@asics.ws ////
//// ////
//// 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 SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
//// POSSIBILITY OF SUCH DAMAGE. ////
//// ////
/////////////////////////////////////////////////////////////////////
// CVS Log
//
// $Id: i2c_master_defines.v,v 1.3 2001-11-05 11:59:25 rherveille Exp $
//
// $Date: 2001-11-05 11:59:25 $
// $Revision: 1.3 $
// $Author: rherveille $
// $Locker: $
// $State: Exp $
//
// Change History:
// $Log: not supported by cvs2svn $
// I2C registers wishbone addresses
// bitcontroller states
`define I2C_CMD_NOP 4'b0000
`define I2C_CMD_START 4'b0001
`define I2C_CMD_STOP 4'b0010
`define I2C_CMD_WRITE 4'b0100
`define I2C_CMD_READ 4'b1000

View File

@ -0,0 +1,256 @@
module i2c_master_top
(
input rst,
input clk,
input[15:0] clk_div_cnt,
// I2C signals
// i2c clock line
input scl_pad_i, // SCL-line input
output scl_pad_o, // SCL-line output (always 1'b0)
output scl_padoen_o, // SCL-line output enable (active low)
// i2c data line
input sda_pad_i, // SDA-line input
output sda_pad_o, // SDA-line output (always 1'b0)
output sda_padoen_o, // SDA-line output enable (active low)
input i2c_addr_2byte, // Is the register address 16bit?
input i2c_read_req, // Read register request
output i2c_read_req_ack, // Read register request response
input i2c_write_req, // Write register request
output i2c_write_req_ack, // Write register request response
input[7:0] i2c_slave_dev_addr, // I2c device address
input[15:0] i2c_slave_reg_addr, // I2c register address
input[7:0] i2c_write_data, // I2c write register data
output reg[7:0] i2c_read_data, // I2c read register data
output reg error // The error indication, generally there is no response
);
//State machine definition
localparam S_IDLE = 0; // Idle state, waiting for read and write
localparam S_WR_DEV_ADDR = 1; // Write device address
localparam S_WR_REG_ADDR = 2; // Write register address
localparam S_WR_DATA = 3; // Write register data
localparam S_WR_ACK = 4; // Write request response
localparam S_WR_ERR_NACK = 5; // Write error, I2C device is not responding
localparam S_RD_DEV_ADDR0 = 6; // I2C read state, first writes the device address and the register address
localparam S_RD_REG_ADDR = 7; // I2C read state, read register address (8bit)
localparam S_RD_DEV_ADDR1 = 8; // Write the device address again
localparam S_RD_DATA = 9; // Read data
localparam S_RD_STOP = 10;
localparam S_WR_STOP = 11;
localparam S_WAIT = 12;
localparam S_WR_REG_ADDR1 = 13;
localparam S_RD_REG_ADDR1 = 14;
localparam S_RD_ACK = 15;
reg start;
reg stop;
reg read;
reg write;
reg ack_in;
reg[7:0] txr;
wire[7:0] rxr;
wire i2c_busy;
wire i2c_al;
wire done;
wire irxack;
reg[3:0] state, next_state;
assign i2c_read_req_ack = (state == S_RD_ACK);
assign i2c_write_req_ack = (state == S_WR_ACK);
always@(posedge clk or posedge rst)
begin
if(rst)
state <= S_IDLE;
else
state <= next_state;
end
always@(*)
begin
case(state)
S_IDLE:
//Waiting for read and write requests
if(i2c_write_req)
next_state <= S_WR_DEV_ADDR;
else if(i2c_read_req)
next_state <= S_RD_DEV_ADDR0;
else
next_state <= S_IDLE;
//Write I2C device address
S_WR_DEV_ADDR:
if(done && irxack)
next_state <= S_WR_ERR_NACK;
else if(done)
next_state <= S_WR_REG_ADDR;
else
next_state <= S_WR_DEV_ADDR;
//Write the address of the I2C register
S_WR_REG_ADDR:
if(done)
//If it is the 8bit register address, it enters the write data state
next_state <= i2c_addr_2byte ? S_WR_REG_ADDR1 : S_WR_DATA;
else
next_state <= S_WR_REG_ADDR;
S_WR_REG_ADDR1:
if(done)
next_state <= S_WR_DATA;
else
next_state <= S_WR_REG_ADDR1;
//Write data
S_WR_DATA:
if(done)
next_state <= S_WR_STOP;
else
next_state <= S_WR_DATA;
S_WR_ERR_NACK:
next_state <= S_WR_STOP;
S_RD_ACK,S_WR_ACK:
next_state <= S_WAIT;
S_WAIT:
next_state <= S_IDLE;
S_RD_DEV_ADDR0:
if(done && irxack)
next_state <= S_WR_ERR_NACK;
else if(done)
next_state <= S_RD_REG_ADDR;
else
next_state <= S_RD_DEV_ADDR0;
S_RD_REG_ADDR:
if(done)
next_state <= i2c_addr_2byte ? S_RD_REG_ADDR1 : S_RD_DEV_ADDR1;
else
next_state <= S_RD_REG_ADDR;
S_RD_REG_ADDR1:
if(done)
next_state <= S_RD_DEV_ADDR1;
else
next_state <= S_RD_REG_ADDR1;
S_RD_DEV_ADDR1:
if(done)
next_state <= S_RD_DATA;
else
next_state <= S_RD_DEV_ADDR1;
S_RD_DATA:
if(done)
next_state <= S_RD_STOP;
else
next_state <= S_RD_DATA;
S_RD_STOP:
if(done)
next_state <= S_RD_ACK;
else
next_state <= S_RD_STOP;
S_WR_STOP:
if(done)
next_state <= S_WR_ACK;
else
next_state <= S_WR_STOP;
default:
next_state <= S_IDLE;
endcase
end
always@(posedge clk or posedge rst)
begin
if(rst)
error <= 1'b0;
else if(state == S_IDLE)
error <= 1'b0;
else if(state == S_WR_ERR_NACK)
error <= 1'b1;
end
always@(posedge clk or posedge rst)
begin
if(rst)
start <= 1'b0;
else if(done)
start <= 1'b0;
else if(state == S_WR_DEV_ADDR || state == S_RD_DEV_ADDR0 || state == S_RD_DEV_ADDR1)
start <= 1'b1;
end
always@(posedge clk or posedge rst)
begin
if(rst)
stop <= 1'b0;
else if(done)
stop <= 1'b0;
else if(state == S_WR_STOP || state == S_RD_STOP)
stop <= 1'b1;
end
always@(posedge clk or posedge rst)
begin
if(rst)
ack_in <= 1'b0;
else
ack_in <= 1'b1;
end
always@(posedge clk or posedge rst)
begin
if(rst)
write <= 1'b0;
else if(done)
write <= 1'b0;
else if(state == S_WR_DEV_ADDR || state == S_WR_REG_ADDR || state == S_WR_REG_ADDR1|| state == S_WR_DATA || state == S_RD_DEV_ADDR0 || state == S_RD_DEV_ADDR1 || state == S_RD_REG_ADDR || state == S_RD_REG_ADDR1)
write <= 1'b1;
end
always@(posedge clk or posedge rst)
begin
if(rst)
read <= 1'b0;
else if(done)
read <= 1'b0;
else if(state == S_RD_DATA)
read <= 1'b1;
end
always@(posedge clk or posedge rst)
begin
if(rst)
i2c_read_data <= 8'h00;
else if(state == S_RD_DATA && done)
i2c_read_data <= rxr;
end
always@(posedge clk or posedge rst)
begin
if(rst)
txr <= 8'd0;
else
case(state)
S_WR_DEV_ADDR,S_RD_DEV_ADDR0:
txr <= {i2c_slave_dev_addr[7:1],1'b0};
S_RD_DEV_ADDR1:
txr <= {i2c_slave_dev_addr[7:1],1'b1};
S_WR_REG_ADDR,S_RD_REG_ADDR:
txr <= (i2c_addr_2byte == 1'b1) ? i2c_slave_reg_addr[15:8] : i2c_slave_reg_addr[7:0];
S_WR_REG_ADDR1,S_RD_REG_ADDR1:
txr <= i2c_slave_reg_addr[7:0];
S_WR_DATA:
txr <= i2c_write_data;
default:
txr <= 8'hff;
endcase
end
i2c_master_byte_ctrl byte_controller (
.clk ( clk ),
.rst ( 1'b0 ),
.nReset ( ~rst ),
.ena ( 1'b1 ),
.clk_cnt ( clk_div_cnt ),
.start ( start ),
.stop ( stop ),
.read ( read ),
.write ( write ),
.ack_in ( ack_in ),
.din ( txr ),
.cmd_ack ( done ),
.ack_out ( irxack ),
.dout ( rxr ),
.i2c_busy ( i2c_busy ),
.i2c_al ( i2c_al ),
.scl_i ( scl_pad_i ),
.scl_o ( scl_pad_o ),
.scl_oen ( scl_padoen_o ),
.sda_i ( sda_pad_i ),
.sda_o ( sda_pad_o ),
.sda_oen ( sda_padoen_o )
);
endmodule

View File

@ -0,0 +1,2 @@
`timescale 1ns / 10ps

View File

@ -0,0 +1,346 @@
//////////////////////////////////////////////////////////////////////////////////
// //
// //
// Author: meisq //
// msq@qq.com //
// ALINX(shanghai) Technology Co.,Ltd //
// heijin //
// WEB: http://www.alinx.cn/ //
// BBS: http://www.heijin.org/ //
// //
//////////////////////////////////////////////////////////////////////////////////
// //
// Copyright (c) 2017,ALINX(shanghai) Technology Co.,Ltd //
// All rights reserved //
// //
// 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. //
// //
//////////////////////////////////////////////////////////////////////////////////
//================================================================================
// Revision History:
// Date By Revision Change Description
//--------------------------------------------------------------------------------
// 2017/7/19 meisq 1.0 Original
//*******************************************************************************/
module lut_ov5640_rgb565_640_480(
input[9:0] lut_index, //Look-up table address
output reg[31:0] lut_data //Device address (8bit I2C address), register address, register data
);
always@(*)
begin
case(lut_index)
10'd 0: lut_data <= {8'h78 , 24'h310311};// system clock from pad, bit[1]
10'd 1: lut_data <= {8'h78 , 24'h300882};// software reset, bit[7]// delay 5ms
10'd 2: lut_data <= {8'h78 , 24'h300842};// software power down, bit[6]
10'd 3: lut_data <= {8'h78 , 24'h310303};// system clock from PLL, bit[1]
10'd 4: lut_data <= {8'h78 , 24'h3017ff};// FREX, Vsync, HREF, PCLK, D[9:6] output enable
10'd 5: lut_data <= {8'h78 , 24'h3018ff};// D[5:0], GPIO[1:0] output enable
10'd 6: lut_data <= {8'h78 , 24'h30341A};// MIPI 10-bit
10'd 7: lut_data <= {8'h78 , 24'h303713};// PLL root divider, bit[4], PLL pre-divider, bit[3:0]
10'd 8: lut_data <= {8'h78 , 24'h310801};// PCLK root divider, bit[5:4], SCLK2x root divider, bit[3:2] // SCLK root divider, bit[1:0]
10'd 9: lut_data <= {8'h78 , 24'h363036};
10'd 10: lut_data <= {8'h78 , 24'h36310e};
10'd 11: lut_data <= {8'h78 , 24'h3632e2};
10'd 12: lut_data <= {8'h78 , 24'h363312};
10'd 13: lut_data <= {8'h78 , 24'h3621e0};
10'd 14: lut_data <= {8'h78 , 24'h3704a0};
10'd 15: lut_data <= {8'h78 , 24'h37035a};
10'd 16: lut_data <= {8'h78 , 24'h371578};
10'd 17: lut_data <= {8'h78 , 24'h371701};
10'd 18: lut_data <= {8'h78 , 24'h370b60};
10'd 19: lut_data <= {8'h78 , 24'h37051a};
10'd 20: lut_data <= {8'h78 , 24'h390502};
10'd 21: lut_data <= {8'h78 , 24'h390610};
10'd 22: lut_data <= {8'h78 , 24'h39010a};
10'd 23: lut_data <= {8'h78 , 24'h373112};
10'd 24: lut_data <= {8'h78 , 24'h360008};// VCM control
10'd 25: lut_data <= {8'h78 , 24'h360133};// VCM control
10'd 26: lut_data <= {8'h78 , 24'h302d60};// system control
10'd 27: lut_data <= {8'h78 , 24'h362052};
10'd 28: lut_data <= {8'h78 , 24'h371b20};
10'd 29: lut_data <= {8'h78 , 24'h471c50};
10'd 30: lut_data <= {8'h78 , 24'h3a1343};// pre-gain = 1.047x
10'd 31: lut_data <= {8'h78 , 24'h3a1800};// gain ceiling
10'd 32: lut_data <= {8'h78 , 24'h3a19f8};// gain ceiling = 15.5x
10'd 33: lut_data <= {8'h78 , 24'h363513};
10'd 34: lut_data <= {8'h78 , 24'h363603};
10'd 35: lut_data <= {8'h78 , 24'h363440};
10'd 36: lut_data <= {8'h78 , 24'h362201}; // 50/60Hz detection 50/60Hz 灯光条纹过滤
10'd 37: lut_data <= {8'h78 , 24'h3c0134};// Band auto, bit[7]
10'd 38: lut_data <= {8'h78 , 24'h3c0428};// threshold low sum
10'd 39: lut_data <= {8'h78 , 24'h3c0598};// threshold high sum
10'd 40: lut_data <= {8'h78 , 24'h3c0600};// light meter 1 threshold[15:8]
10'd 41: lut_data <= {8'h78 , 24'h3c0708};// light meter 1 threshold[7:0]
10'd 42: lut_data <= {8'h78 , 24'h3c0800};// light meter 2 threshold[15:8]
10'd 43: lut_data <= {8'h78 , 24'h3c091c};// light meter 2 threshold[7:0]
10'd 44: lut_data <= {8'h78 , 24'h3c0a9c};// sample number[15:8]
10'd 45: lut_data <= {8'h78 , 24'h3c0b40};// sample number[7:0]
10'd 46: lut_data <= {8'h78 , 24'h381000};// Timing Hoffset[11:8]
10'd 47: lut_data <= {8'h78 , 24'h381110};// Timing Hoffset[7:0]
10'd 48: lut_data <= {8'h78 , 24'h381200};// Timing Voffset[10:8]
10'd 49: lut_data <= {8'h78 , 24'h370864};
10'd 50: lut_data <= {8'h78 , 24'h400102};// BLC start from line 2
10'd 51: lut_data <= {8'h78 , 24'h40051a};// BLC always update
10'd 52: lut_data <= {8'h78 , 24'h300000};// enable blocks
10'd 53: lut_data <= {8'h78 , 24'h3004ff};// enable clocks
10'd 54: lut_data <= {8'h78 , 24'h300e58};// MIPI power down, DVP enable
10'd 55: lut_data <= {8'h78 , 24'h302e00};
10'd 56: lut_data <= {8'h78 , 24'h430060};// RGB565
10'd 57: lut_data <= {8'h78 , 24'h501f01};// ISP RGB
10'd 58: lut_data <= {8'h78 , 24'h440e00};
10'd 59: lut_data <= {8'h78 , 24'h5000a7}; // Lenc on, raw gamma on, BPC on, WPC on, CIP on // AEC target 自动曝光控制
10'd 60: lut_data <= {8'h78 , 24'h3a0f30};// stable range in high
10'd 61: lut_data <= {8'h78 , 24'h3a1028};// stable range in low
10'd 62: lut_data <= {8'h78 , 24'h3a1b30};// stable range out high
10'd 63: lut_data <= {8'h78 , 24'h3a1e26};// stable range out low
10'd 64: lut_data <= {8'h78 , 24'h3a1160};// fast zone high
10'd 65: lut_data <= {8'h78 , 24'h3a1f14};// fast zone low// Lens correction for ? 镜头补偿
10'd 66: lut_data <= {8'h78 , 24'h580023};
10'd 67: lut_data <= {8'h78 , 24'h580114};
10'd 68: lut_data <= {8'h78 , 24'h58020f};
10'd 69: lut_data <= {8'h78 , 24'h58030f};
10'd 70: lut_data <= {8'h78 , 24'h580412};
10'd 71: lut_data <= {8'h78 , 24'h580526};
10'd 72: lut_data <= {8'h78 , 24'h58060c};
10'd 73: lut_data <= {8'h78 , 24'h580708};
10'd 74: lut_data <= {8'h78 , 24'h580805};
10'd 75: lut_data <= {8'h78 , 24'h580905};
10'd 76: lut_data <= {8'h78 , 24'h580a08};
10'd 77: lut_data <= {8'h78 , 24'h580b0d};
10'd 78: lut_data <= {8'h78 , 24'h580c08};
10'd 79: lut_data <= {8'h78 , 24'h580d03};
10'd 80: lut_data <= {8'h78 , 24'h580e00};
10'd 81: lut_data <= {8'h78 , 24'h580f00};
10'd 82: lut_data <= {8'h78 , 24'h581003};
10'd 83: lut_data <= {8'h78 , 24'h581109};
10'd 84: lut_data <= {8'h78 , 24'h581207};
10'd 85: lut_data <= {8'h78 , 24'h581303};
10'd 86: lut_data <= {8'h78 , 24'h581400};
10'd 87: lut_data <= {8'h78 , 24'h581501};
10'd 88: lut_data <= {8'h78 , 24'h581603};
10'd 89: lut_data <= {8'h78 , 24'h581708};
10'd 90: lut_data <= {8'h78 , 24'h58180d};
10'd 91: lut_data <= {8'h78 , 24'h581908};
10'd 92: lut_data <= {8'h78 , 24'h581a05};
10'd 93: lut_data <= {8'h78 , 24'h581b06};
10'd 94: lut_data <= {8'h78 , 24'h581c08};
10'd 95: lut_data <= {8'h78 , 24'h581d0e};
10'd 96: lut_data <= {8'h78 , 24'h581e29};
10'd 97: lut_data <= {8'h78 , 24'h581f17};
10'd 98: lut_data <= {8'h78 , 24'h582011};
10'd 99: lut_data <= {8'h78 , 24'h582111};
10'd100: lut_data <= {8'h78 , 24'h582215};
10'd101: lut_data <= {8'h78 , 24'h582328};
10'd102: lut_data <= {8'h78 , 24'h582446};
10'd103: lut_data <= {8'h78 , 24'h582526};
10'd104: lut_data <= {8'h78 , 24'h582608};
10'd105: lut_data <= {8'h78 , 24'h582726};
10'd106: lut_data <= {8'h78 , 24'h582864};
10'd107: lut_data <= {8'h78 , 24'h582926};
10'd108: lut_data <= {8'h78 , 24'h582a24};
10'd109: lut_data <= {8'h78 , 24'h582b22};
10'd110: lut_data <= {8'h78 , 24'h582c24};
10'd111: lut_data <= {8'h78 , 24'h582d24};
10'd112: lut_data <= {8'h78 , 24'h582e06};
10'd113: lut_data <= {8'h78 , 24'h582f22};
10'd114: lut_data <= {8'h78 , 24'h583040};
10'd115: lut_data <= {8'h78 , 24'h583142};
10'd116: lut_data <= {8'h78 , 24'h583224};
10'd117: lut_data <= {8'h78 , 24'h583326};
10'd118: lut_data <= {8'h78 , 24'h583424};
10'd119: lut_data <= {8'h78 , 24'h583522};
10'd120: lut_data <= {8'h78 , 24'h583622};
10'd121: lut_data <= {8'h78 , 24'h583726};
10'd122: lut_data <= {8'h78 , 24'h583844};
10'd123: lut_data <= {8'h78 , 24'h583924};
10'd124: lut_data <= {8'h78 , 24'h583a26};
10'd125: lut_data <= {8'h78 , 24'h583b28};
10'd126: lut_data <= {8'h78 , 24'h583c42};
10'd127: lut_data <= {8'h78 , 24'h583dce};// lenc BR offset // AWB 自动白平衡
10'd128: lut_data <= {8'h78 , 24'h5180ff};// AWB B block
10'd129: lut_data <= {8'h78 , 24'h5181f2};// AWB control
10'd130: lut_data <= {8'h78 , 24'h518200};// [7:4] max local counter, [3:0] max fast counter
10'd131: lut_data <= {8'h78 , 24'h518314};// AWB advanced
10'd132: lut_data <= {8'h78 , 24'h518425};
10'd133: lut_data <= {8'h78 , 24'h518524};
10'd134: lut_data <= {8'h78 , 24'h518609};
10'd135: lut_data <= {8'h78 , 24'h518709};
10'd136: lut_data <= {8'h78 , 24'h518809};
10'd137: lut_data <= {8'h78 , 24'h518975};
10'd138: lut_data <= {8'h78 , 24'h518a54};
10'd139: lut_data <= {8'h78 , 24'h518be0};
10'd140: lut_data <= {8'h78 , 24'h518cb2};
10'd141: lut_data <= {8'h78 , 24'h518d42};
10'd142: lut_data <= {8'h78 , 24'h518e3d};
10'd143: lut_data <= {8'h78 , 24'h518f56};
10'd144: lut_data <= {8'h78 , 24'h519046};
10'd145: lut_data <= {8'h78 , 24'h5191f8};// AWB top limit
10'd146: lut_data <= {8'h78 , 24'h519204};// AWB bottom limit
10'd147: lut_data <= {8'h78 , 24'h519370};// red limit
10'd148: lut_data <= {8'h78 , 24'h5194f0};// green limit
10'd149: lut_data <= {8'h78 , 24'h5195f0};// blue limit
10'd150: lut_data <= {8'h78 , 24'h519603};// AWB control
10'd151: lut_data <= {8'h78 , 24'h519701};// local limit
10'd152: lut_data <= {8'h78 , 24'h519804};
10'd153: lut_data <= {8'h78 , 24'h519912};
10'd154: lut_data <= {8'h78 , 24'h519a04};
10'd155: lut_data <= {8'h78 , 24'h519b00};
10'd156: lut_data <= {8'h78 , 24'h519c06};
10'd157: lut_data <= {8'h78 , 24'h519d82};
10'd158: lut_data <= {8'h78 , 24'h519e38};// AWB control // Gamma 伽玛曲线
10'd159: lut_data <= {8'h78 , 24'h548001};// Gamma bias plus on, bit[0]
10'd160: lut_data <= {8'h78 , 24'h548108};
10'd161: lut_data <= {8'h78 , 24'h548214};
10'd162: lut_data <= {8'h78 , 24'h548328};
10'd163: lut_data <= {8'h78 , 24'h548451};
10'd164: lut_data <= {8'h78 , 24'h548565};
10'd165: lut_data <= {8'h78 , 24'h548671};
10'd166: lut_data <= {8'h78 , 24'h54877d};
10'd167: lut_data <= {8'h78 , 24'h548887};
10'd168: lut_data <= {8'h78 , 24'h548991};
10'd169: lut_data <= {8'h78 , 24'h548a9a};
10'd170: lut_data <= {8'h78 , 24'h548baa};
10'd171: lut_data <= {8'h78 , 24'h548cb8};
10'd172: lut_data <= {8'h78 , 24'h548dcd};
10'd173: lut_data <= {8'h78 , 24'h548edd};
10'd174: lut_data <= {8'h78 , 24'h548fea};
10'd175: lut_data <= {8'h78 , 24'h54901d};// color matrix 色彩矩阵
10'd176: lut_data <= {8'h78 , 24'h53811e};// CMX1 for Y
10'd177: lut_data <= {8'h78 , 24'h53825b};// CMX2 for Y
10'd178: lut_data <= {8'h78 , 24'h538308};// CMX3 for Y
10'd179: lut_data <= {8'h78 , 24'h53840a};// CMX4 for U
10'd180: lut_data <= {8'h78 , 24'h53857e};// CMX5 for U
10'd181: lut_data <= {8'h78 , 24'h538688};// CMX6 for U
10'd182: lut_data <= {8'h78 , 24'h53877c};// CMX7 for V
10'd183: lut_data <= {8'h78 , 24'h53886c};// CMX8 for V
10'd184: lut_data <= {8'h78 , 24'h538910};// CMX9 for V
10'd185: lut_data <= {8'h78 , 24'h538a01};// sign[9]
10'd186: lut_data <= {8'h78 , 24'h538b98}; // sign[8:1] // UV adjust UV色彩饱和度调整
10'd187: lut_data <= {8'h78 , 24'h558006};// saturation on, bit[1]
10'd188: lut_data <= {8'h78 , 24'h558340};
10'd189: lut_data <= {8'h78 , 24'h558410};
10'd190: lut_data <= {8'h78 , 24'h558910};
10'd191: lut_data <= {8'h78 , 24'h558a00};
10'd192: lut_data <= {8'h78 , 24'h558bf8};
10'd193: lut_data <= {8'h78 , 24'h501d40};// enable manual offset of contrast// CIP 锐化和降噪
10'd194: lut_data <= {8'h78 , 24'h530008};// CIP sharpen MT threshold 1
10'd195: lut_data <= {8'h78 , 24'h530130};// CIP sharpen MT threshold 2
10'd196: lut_data <= {8'h78 , 24'h530210};// CIP sharpen MT offset 1
10'd197: lut_data <= {8'h78 , 24'h530300};// CIP sharpen MT offset 2
10'd198: lut_data <= {8'h78 , 24'h530408};// CIP DNS threshold 1
10'd199: lut_data <= {8'h78 , 24'h530530};// CIP DNS threshold 2
10'd200: lut_data <= {8'h78 , 24'h530608};// CIP DNS offset 1
10'd201: lut_data <= {8'h78 , 24'h530716};// CIP DNS offset 2
10'd202: lut_data <= {8'h78 , 24'h530908};// CIP sharpen TH threshold 1
10'd203: lut_data <= {8'h78 , 24'h530a30};// CIP sharpen TH threshold 2
10'd204: lut_data <= {8'h78 , 24'h530b04};// CIP sharpen TH offset 1
10'd205: lut_data <= {8'h78 , 24'h530c06};// CIP sharpen TH offset 2
10'd206: lut_data <= {8'h78 , 24'h502500};
10'd207: lut_data <= {8'h78 , 24'h300802}; // wake up from standby, bit[6]
10'd208: lut_data <= {8'h78 , 24'h303511};// PLL
10'd209: lut_data <= {8'h78 , 24'h303669};// PLL
10'd210: lut_data <= {8'h78 , 24'h3c0708};// light meter 1 threshold [7:0]
10'd211: lut_data <= {8'h78 , 24'h382041};// Sensor flip off, ISP flip on
10'd212: lut_data <= {8'h78 , 24'h382101};// Sensor mirror on, ISP mirror on, H binning on
10'd213: lut_data <= {8'h78 , 24'h381431};// X INC
10'd214: lut_data <= {8'h78 , 24'h381531};// Y INC
10'd215: lut_data <= {8'h78 , 24'h380000};// HS: X address start high byte
10'd216: lut_data <= {8'h78 , 24'h380100};// HS: X address start low byte
10'd217: lut_data <= {8'h78 , 24'h380200};// VS: Y address start high byte
10'd218: lut_data <= {8'h78 , 24'h380304};// VS: Y address start high byte
10'd219: lut_data <= {8'h78 , 24'h38040a};// HW (HE)
10'd220: lut_data <= {8'h78 , 24'h38053f};// HW (HE)
10'd221: lut_data <= {8'h78 , 24'h380607};// VH (VE)
10'd222: lut_data <= {8'h78 , 24'h38079b};// VH (VE)
10'd223: lut_data <= {8'h78 , 24'h380803};// DVPHO
10'd224: lut_data <= {8'h78 , 24'h380920};// DVPHO
10'd225: lut_data <= {8'h78 , 24'h380a02};// DVPVO
10'd226: lut_data <= {8'h78 , 24'h380b58};// DVPVO
10'd227: lut_data <= {8'h78 , 24'h380c07};// HTS //Total horizontal size 800
10'd228: lut_data <= {8'h78 , 24'h380d68};// HTS
10'd229: lut_data <= {8'h78 , 24'h380e03};// VTS //total vertical size 500
10'd230: lut_data <= {8'h78 , 24'h380fd8};// VTS
10'd231: lut_data <= {8'h78 , 24'h381306};// Timing Voffset
10'd232: lut_data <= {8'h78 , 24'h361800};
10'd233: lut_data <= {8'h78 , 24'h361229};
10'd234: lut_data <= {8'h78 , 24'h370952};
10'd235: lut_data <= {8'h78 , 24'h370c03};
10'd236: lut_data <= {8'h78 , 24'h3a0217};// 60Hz max exposure, night mode 5fps
10'd237: lut_data <= {8'h78 , 24'h3a0310};// 60Hz max exposure // banding filters are calculated automatically in camera driver
10'd238: lut_data <= {8'h78 , 24'h3a1417};// 50Hz max exposure, night mode 5fps
10'd239: lut_data <= {8'h78 , 24'h3a1510};// 50Hz max exposure
10'd240: lut_data <= {8'h78 , 24'h400402};// BLC 2 lines
10'd241: lut_data <= {8'h78 , 24'h30021c};// reset JFIFO, SFIFO, JPEG
10'd242: lut_data <= {8'h78 , 24'h3006c3};// disable clock of JPEG2x, JPEG
10'd243: lut_data <= {8'h78 , 24'h471303};// JPEG mode 3
10'd244: lut_data <= {8'h78 , 24'h440704};// Quantization scale
10'd245: lut_data <= {8'h78 , 24'h460b35};
10'd246: lut_data <= {8'h78 , 24'h460c22};
10'd247: lut_data <= {8'h78 , 24'h483722}; // DVP CLK divider
10'd248: lut_data <= {8'h78 , 24'h382402}; // DVP CLK divider
10'd249: lut_data <= {8'h78 , 24'h5001a3}; // SDE on, scale on, UV average off, color matrix on, AWB on
10'd250: lut_data <= {8'h78 , 24'h350300}; // AEC/AGC on
10'd251: lut_data <= {8'h78 , 24'h303521};// PLL input clock =24Mhz, PCLK =84Mhz
10'd252: lut_data <= {8'h78 , 24'h303669};// PLL
10'd253: lut_data <= {8'h78 , 24'h3c0707}; // lightmeter 1 threshold[7:0]
10'd254: lut_data <= {8'h78 , 24'h382047}; // flip
10'd255: lut_data <= {8'h78 , 24'h382101}; // mirror
10'd256: lut_data <= {8'h78 , 24'h381431}; // timing X inc
10'd257: lut_data <= {8'h78 , 24'h381531}; // timing Y inc
10'd258: lut_data <= {8'h78 , 24'h380000}; // HS
10'd259: lut_data <= {8'h78 , 24'h380100}; // HS
10'd260: lut_data <= {8'h78 , 24'h380200}; // VS
10'd261: lut_data <= {8'h78 , 24'h380304}; // VS
10'd262: lut_data <= {8'h78 , 24'h38040a}; // HW (HE)
10'd263: lut_data <= {8'h78 , 24'h38053f}; // HW (HE)
10'd264: lut_data <= {8'h78 , 24'h380607}; // VH (VE)
10'd265: lut_data <= {8'h78 , 24'h38079f}; // VH (VE)
10'd266: lut_data <= {8'h78 , 24'h380802}; // DVPHO (1280)->1024
10'd267: lut_data <= {8'h78 , 24'h380980}; // DVPHO (1280)->1024
10'd268: lut_data <= {8'h78 , 24'h380a01}; // DVPVO (720)->
10'd269: lut_data <= {8'h78 , 24'h380be0}; // DVPVO (720)->
10'd270: lut_data <= {8'h78 , 24'h380c07}; // HTS
10'd271: lut_data <= {8'h78 , 24'h380d68}; // HTS
10'd272: lut_data <= {8'h78 , 24'h380e03}; // VTS
10'd273: lut_data <= {8'h78 , 24'h380fd8}; // VTS
10'd274: lut_data <= {8'h78 , 24'h381304}; // timing V offset
10'd275: lut_data <= {8'h78 , 24'h361800};
10'd276: lut_data <= {8'h78 , 24'h361229};
10'd277: lut_data <= {8'h78 , 24'h370952};
10'd278: lut_data <= {8'h78 , 24'h370c03};
10'd279: lut_data <= {8'h78 , 24'h3a0202}; // 60Hz max exposure
10'd280: lut_data <= {8'h78 , 24'h3a03e0}; // 60Hz max exposure
10'd281: lut_data <= {8'h78 , 24'h3a0800}; // B50 step
10'd282: lut_data <= {8'h78 , 24'h3a096f}; // B50 step
10'd283: lut_data <= {8'h78 , 24'h3a0a00}; // B60 step
10'd284: lut_data <= {8'h78 , 24'h3a0b5c}; // B60 step
10'd285: lut_data <= {8'h78 , 24'h3a0e06}; // 50Hz max band
10'd286: lut_data <= {8'h78 , 24'h3a0d08}; // 60Hz max band
10'd287: lut_data <= {8'h78 , 24'h3a1402}; // 50Hz max exposure
10'd288: lut_data <= {8'h78 , 24'h3a15e0}; // 50Hz max exposure
10'd289: lut_data <= {8'h78 , 24'h400402}; // BLC line number
10'd290: lut_data <= {8'h78 , 24'h30021c}; // reset JFIFO, SFIFO, JPG
10'd291: lut_data <= {8'h78 , 24'h3006c3}; // disable clock of JPEG2x, JPEG
10'd292: lut_data <= {8'h78 , 24'h471303}; // JPEG mode 3
10'd293: lut_data <= {8'h78 , 24'h440704}; // Quantization sacle
10'd294: lut_data <= {8'h78 , 24'h460b37};
10'd295: lut_data <= {8'h78 , 24'h460c20};
10'd296: lut_data <= {8'h78 , 24'h483716}; // MIPI global timing
10'd297: lut_data <= {8'h78 , 24'h382404}; // PCLK manual divider
10'd298: lut_data <= {8'h78 , 24'h350300}; // AEC/AGC on
10'd299: lut_data <= {8'h78 , 24'h301602}; //Strobe output enable
10'd300: lut_data <= {8'h78 , 24'h3b070a}; //FREX strobe mode1
10'd301: lut_data <= {8'h78 , 24'h3b0083}; //STROBE CTRL: strobe request ON, Strobe mode: LED3
10'd302: lut_data <= {8'h78 , 24'h3b0000}; //STROBE CTRL: strobe request OFF
default:lut_data <= {8'hff,16'hffff,8'hff};
endcase
end
endmodule

View File

@ -0,0 +1,179 @@
`timescale 1ns/1ps
module serdes_4b_10to1 (
input clk, // clock input
input clkx5, // 5x clock input
input [9:0] datain_0, // input data for serialisation
input [9:0] datain_1, // input data for serialisation
input [9:0] datain_2, // input data for serialisation
input [9:0] datain_3, // input data for serialisation
output dataout_0_p, // out DDR data
output dataout_0_n, // out DDR data
output dataout_1_p, // out DDR data
output dataout_1_n, // out DDR data
output dataout_2_p, // out DDR data
output dataout_2_n, // out DDR data
output dataout_3_p, // out DDR data
output dataout_3_n // out DDR data
) ;
reg [2:0] TMDS_mod5 = 0; // modulus 5 counter
reg [4:0] TMDS_shift_0h = 0, TMDS_shift_0l = 0;
reg [4:0] TMDS_shift_1h = 0, TMDS_shift_1l = 0;
reg [4:0] TMDS_shift_2h = 0, TMDS_shift_2l = 0;
reg [4:0] TMDS_shift_3h = 0, TMDS_shift_3l = 0;
wire [4:0] TMDS_0_l = {datain_0[9],datain_0[7],datain_0[5],datain_0[3],datain_0[1]};
wire [4:0] TMDS_0_h = {datain_0[8],datain_0[6],datain_0[4],datain_0[2],datain_0[0]};
wire [4:0] TMDS_1_l = {datain_1[9],datain_1[7],datain_1[5],datain_1[3],datain_1[1]};
wire [4:0] TMDS_1_h = {datain_1[8],datain_1[6],datain_1[4],datain_1[2],datain_1[0]};
wire [4:0] TMDS_2_l = {datain_2[9],datain_2[7],datain_2[5],datain_2[3],datain_3[1]};
wire [4:0] TMDS_2_h = {datain_2[8],datain_2[6],datain_2[4],datain_2[2],datain_3[0]};
wire [4:0] TMDS_3_l = {datain_3[9],datain_3[7],datain_3[5],datain_3[3],datain_3[1]};
wire [4:0] TMDS_3_h = {datain_3[8],datain_3[6],datain_3[4],datain_3[2],datain_3[0]};
always @(posedge clkx5)
begin
TMDS_shift_0h <= TMDS_mod5[2] ? TMDS_0_h : TMDS_shift_0h[4:1];
TMDS_shift_0l <= TMDS_mod5[2] ? TMDS_0_l : TMDS_shift_0l[4:1];
TMDS_shift_1h <= TMDS_mod5[2] ? TMDS_1_h : TMDS_shift_1h[4:1];
TMDS_shift_1l <= TMDS_mod5[2] ? TMDS_1_l : TMDS_shift_1l[4:1];
TMDS_shift_2h <= TMDS_mod5[2] ? TMDS_2_h : TMDS_shift_2h[4:1];
TMDS_shift_2l <= TMDS_mod5[2] ? TMDS_2_l : TMDS_shift_2l[4:1];
TMDS_shift_3h <= TMDS_mod5[2] ? TMDS_3_h : TMDS_shift_3h[4:1];
TMDS_shift_3l <= TMDS_mod5[2] ? TMDS_3_l : TMDS_shift_3l[4:1];
TMDS_mod5 <= (TMDS_mod5[2]) ? 3'd0 : TMDS_mod5 + 3'd1;
end
//-p
ODDR2 #(
.DDR_ALIGNMENT("C0"), // Sets output alignment to "NONE", "C0" or "C1"
.INIT(1'b0), // Sets initial state of the Q output to 1'b0 or 1'b1
.SRTYPE("ASYNC") // Specifies "SYNC" or "ASYNC" set/reset
) U1_ODDR2
(
.Q(dataout_3_p), // 1-bit DDR output data
.C0(clkx5), // 1-bit clock input
.C1(~clkx5), // 1-bit clock input
.CE(1'b1), // 1-bit clock enable input
.D0(TMDS_shift_3h[0]), // 1-bit data input (associated with C0)
.D1(TMDS_shift_3l[0]), // 1-bit data input (associated with C1)
.R(1'b0), // 1-bit reset input
.S(1'b0) // 1-bit set input
);
ODDR2 #(
.DDR_ALIGNMENT("C0"), // Sets output alignment to "NONE", "C0" or "C1"
.INIT(1'b0), // Sets initial state of the Q output to 1'b0 or 1'b1
.SRTYPE("ASYNC") // Specifies "SYNC" or "ASYNC" set/reset
) U2_ODDR2
(
.Q(dataout_2_p), // 1-bit DDR output data
.C0(clkx5), // 1-bit clock input
.C1(~clkx5), // 1-bit clock input
.CE(1'b1), // 1-bit clock enable input
.D0(TMDS_shift_2h[0]), // 1-bit data input (associated with C0)
.D1(TMDS_shift_2l[0]), // 1-bit data input (associated with C1)
.R(1'b0), // 1-bit reset input
.S(1'b0) // 1-bit set input
);
ODDR2 #(
.DDR_ALIGNMENT("C0"), // Sets output alignment to "NONE", "C0" or "C1"
.INIT(1'b0), // Sets initial state of the Q output to 1'b0 or 1'b1
.SRTYPE("ASYNC") // Specifies "SYNC" or "ASYNC" set/reset
) U3_ODDR2
(
.Q(dataout_1_p), // 1-bit DDR output data
.C0(clkx5), // 1-bit clock input
.C1(~clkx5), // 1-bit clock input
.CE(1'b1), // 1-bit clock enable input
.D0(TMDS_shift_1h[0]), // 1-bit data input (associated with C0)
.D1(TMDS_shift_1l[0]), // 1-bit data input (associated with C1)
.R(1'b0), // 1-bit reset input
.S(1'b0) // 1-bit set input
);
ODDR2 #(
.DDR_ALIGNMENT("C0"), // Sets output alignment to "NONE", "C0" or "C1"
.INIT(1'b0), // Sets initial state of the Q output to 1'b0 or 1'b1
.SRTYPE("ASYNC") // Specifies "SYNC" or "ASYNC" set/reset
) U4_ODDR2
(
.Q(dataout_0_p), // 1-bit DDR output data
.C0(clkx5), // 1-bit clock input
.C1(~clkx5), // 1-bit clock input
.CE(1'b1), // 1-bit clock enable input
.D0(TMDS_shift_0h[0]), // 1-bit data input (associated with C0)
.D1(TMDS_shift_0l[0]), // 1-bit data input (associated with C1)
.R(1'b0), // 1-bit reset input
.S(1'b0) // 1-bit set input
);
//-n
ODDR2 #(
.DDR_ALIGNMENT("C0"), // Sets output alignment to "NONE", "C0" or "C1"
.INIT(1'b0), // Sets initial state of the Q output to 1'b0 or 1'b1
.SRTYPE("ASYNC") // Specifies "SYNC" or "ASYNC" set/reset
) U5_ODDR2
(
.Q(dataout_3_n), // 1-bit DDR output data
.C0(clkx5), // 1-bit clock input
.C1(~clkx5), // 1-bit clock input
.CE(1'b1), // 1-bit clock enable input
.D0(~TMDS_shift_3h[0]), // 1-bit data input (associated with C0)
.D1(~TMDS_shift_3l[0]), // 1-bit data input (associated with C1)
.R(1'b0), // 1-bit reset input
.S(1'b0) // 1-bit set input
);
ODDR2 #(
.DDR_ALIGNMENT("C0"), // Sets output alignment to "NONE", "C0" or "C1"
.INIT(1'b0), // Sets initial state of the Q output to 1'b0 or 1'b1
.SRTYPE("ASYNC") // Specifies "SYNC" or "ASYNC" set/reset
) U6_ODDR2
(
.Q(dataout_2_n), // 1-bit DDR output data
.C0(clkx5), // 1-bit clock input
.C1(~clkx5), // 1-bit clock input
.CE(1'b1), // 1-bit clock enable input
.D0(~TMDS_shift_2h[0]), // 1-bit data input (associated with C0)
.D1(~TMDS_shift_2l[0]), // 1-bit data input (associated with C1)
.R(1'b0), // 1-bit reset input
.S(1'b0) // 1-bit set input
);
ODDR2 #(
.DDR_ALIGNMENT("C0"), // Sets output alignment to "NONE", "C0" or "C1"
.INIT(1'b0), // Sets initial state of the Q output to 1'b0 or 1'b1
.SRTYPE("ASYNC") // Specifies "SYNC" or "ASYNC" set/reset
) U7_ODDR2
(
.Q(dataout_1_n), // 1-bit DDR output data
.C0(clkx5), // 1-bit clock input
.C1(~clkx5), // 1-bit clock input
.CE(1'b1), // 1-bit clock enable input
.D0(~TMDS_shift_1h[0]), // 1-bit data input (associated with C0)
.D1(~TMDS_shift_1l[0]), // 1-bit data input (associated with C1)
.R(1'b0), // 1-bit reset input
.S(1'b0) // 1-bit set input
);
ODDR2 #(
.DDR_ALIGNMENT("C0"), // Sets output alignment to "NONE", "C0" or "C1"
.INIT(1'b0), // Sets initial state of the Q output to 1'b0 or 1'b1
.SRTYPE("ASYNC") // Specifies "SYNC" or "ASYNC" set/reset
) U8_ODDR2
(
.Q(dataout_0_n), // 1-bit DDR output data
.C0(clkx5), // 1-bit clock input
.C1(~clkx5), // 1-bit clock input
.CE(1'b1), // 1-bit clock enable input
.D0(~TMDS_shift_0h[0]), // 1-bit data input (associated with C0)
.D1(~TMDS_shift_0l[0]), // 1-bit data input (associated with C1)
.R(1'b0), // 1-bit reset input
.S(1'b0) // 1-bit set input
);
endmodule

View File

@ -0,0 +1 @@
`define VIDEO_640_480

View File

@ -0,0 +1,113 @@
//////////////////////////////////////////////////////////////////////////////////
// //
// //
// Author: meisq //
// msq@qq.com //
// ALINX(shanghai) Technology Co.,Ltd //
// heijin //
// WEB: http://www.alinx.cn/ //
// BBS: http://www.heijin.org/ //
// //
//////////////////////////////////////////////////////////////////////////////////
// //
// Copyright (c) 2017,ALINX(shanghai) Technology Co.,Ltd //
// All rights reserved //
// //
// 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. //
// //
//////////////////////////////////////////////////////////////////////////////////
//================================================================================
// Revision History:
// Date By Revision Change Description
//--------------------------------------------------------------------------------
// 2017/7/19 meisq 1.0 Original
//*******************************************************************************/
module video_timing_data
#(
parameter DATA_WIDTH = 16 // Video data one clock data width
)
(
input video_clk, // Video pixel clock
input rst,
output reg read_req, // Start reading a frame of data
input read_req_ack, // Read request response
output read_en, // Read data enable
input[DATA_WIDTH - 1:0] read_data, // Read data
output hs, // horizontal synchronization
output vs, // vertical synchronization
output de, // video valid
output[DATA_WIDTH - 1:0] vout_data // video data
);
wire video_hs;
wire video_vs;
wire video_de;
//delay video_hs video_vs video_de 2 clock cycles
reg video_hs_d0;
reg video_vs_d0;
reg video_de_d0;
reg video_hs_d1;
reg video_vs_d1;
reg video_de_d1;
reg[DATA_WIDTH - 1:0] vout_data_r;
assign read_en = video_de;
assign hs = video_hs_d1;
assign vs = video_vs_d1;
assign de = video_de_d1;
assign vout_data = vout_data_r;
always@(posedge video_clk or posedge rst)
begin
if(rst == 1'b1)
begin
video_hs_d0 <= 1'b0;
video_vs_d0 <= 1'b0;
video_de_d0 <= 1'b0;
end
else
begin
//delay video_hs video_vs video_de 2 clock cycles
video_hs_d0 <= video_hs;
video_vs_d0 <= video_vs;
video_de_d0 <= video_de;
video_hs_d1 <= video_hs_d0;
video_vs_d1 <= video_vs_d0;
video_de_d1 <= video_de_d0;
end
end
always@(posedge video_clk or posedge rst)
begin
if(rst == 1'b1)
vout_data_r <= {DATA_WIDTH{1'b0}};
else if(video_de_d0)
vout_data_r <= read_data;
else
vout_data_r <= {DATA_WIDTH{1'b0}};
end
always@(posedge video_clk or posedge rst)
begin
if(rst == 1'b1)
read_req <= 1'b0;
else if(video_vs_d0 & ~video_vs) //vertical synchronization edge (the rising or falling edges are OK)
read_req <= 1'b1;
else if(read_req_ack)
read_req <= 1'b0;
end
color_bar color_bar_m0(
.clk(video_clk),
.rst(rst),
.hs(video_hs),
.vs(video_vs),
.de(video_de),
.rgb_r(),
.rgb_g(),
.rgb_b()
);
endmodule

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,98 @@
/* *****************************************************************
* This code is released under the MIT License.
* Copyright (c) 2020 Xuanzhi LIU, Qiao HU, Zongwu HE
*
* For latest version of this code or to issue a problem,
* please visit: <https://github.com/WalkerLau/DetectHumanFaces>
*
* Note: the above information must be kept whenever or wherever the codes are used.
*
* *****************************************************************/
module igniter #(
parameter ADDRWIDTH = 12)
(
//SYSTEM
input wire pclk,
input wire presetn,
output reg ignite_acc,
input ignite_ready,
output reg ignite_cam,
input ignite_cam_ready,
output reg write_addr_index,
output reg read_addr_index,
//APB
input wire psel,
input wire [ADDRWIDTH-1:0] paddr,
input wire penable,
input wire pwrite,
input wire [31:0] pwdata,
output reg [31:0] prdata,
output wire pready,
output wire pslverr
);
assign pready = 1'b1; //always ready. Can be customized to support waitstate if required.
assign pslverr = 1'b0; //alwyas OKAY. Can be customized to support error response if required.
assign write_en = psel & penable & pwrite;
assign read_en = psel & penable & (~pwrite);
// Camera Igniter
always @ (posedge pclk or negedge presetn) begin
if(~presetn)begin
ignite_cam <= 1'b0;
end
else begin
if(ignite_cam_ready == 1'b1) begin
ignite_cam <= 1'b0;
end
else if((write_en == 1'b1) && (pwdata == 32'hca)) begin
ignite_cam <= 1'b1;
end
end
end
// Accelerator Igniter
always @ (posedge pclk or negedge presetn) begin
if(~presetn)begin
ignite_acc <= 1'b0;
end
else begin
if(ignite_ready == 1'b1) begin
ignite_acc <= 1'b0;
end
else if((write_en == 1'b1) && (pwdata == 32'd1514)) begin
ignite_acc <= 1'b1;
end
end
end
// pixel address index
always @ (posedge pclk or negedge presetn) begin
if(~presetn)begin
prdata <= 32'd0;
end
else if(read_en == 1'b1) begin
prdata <= {31'b0, write_addr_index};
end
end
// draw kuangkuang
always @ (posedge pclk or negedge presetn) begin
if(~presetn)begin
write_addr_index <= 1'd0;
read_addr_index <= 1'd1;
end
else begin
if((write_en == 1'b1) && (pwdata == 32'hda)) begin
read_addr_index = write_addr_index;
write_addr_index = write_addr_index + 1'd1;
end
end
end
endmodule

View File

@ -0,0 +1,115 @@
//-----------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from ARM Limited.
//
// (C) COPYRIGHT 2010-2013 ARM Limited.
// ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from ARM Limited.
//
// SVN Information
//
// Checked In : $Date: 2012-07-31 10:47:23 +0100 (Tue, 31 Jul 2012) $
//
// Revision : $Revision: 217027 $
//
// Release Information : Cortex-M System Design Kit-r1p0-00rel0
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Abstract : AMBA APB3 example slave interface module.
// Convert APB BUS protocol to simple register read write protocol
//-----------------------------------------------------------------------------
module cmsdk_apb3_eg_slave_interface_led #(
// parameter for address width
parameter ADDRWIDTH = 12)
(
// IO declaration
input wire pclk, // pclk
input wire presetn, // reset
// apb interface inputs
input wire psel,
input wire [ADDRWIDTH-1:0] paddr,
input wire penable,
input wire pwrite,
input wire [31:0] pwdata,
// apb interface outputs
output wire [31:0] prdata,
output wire pready,
output wire pslverr,
// LED write interface
output wire [31:0] ledNumIn
);
//------------------------------------------------------------------------------
// module logic start
//------------------------------------------------------------------------------
reg [31:0] Reg2LED;
wire write_en;
// APB interface
assign prdata = 32'b0;
assign pready = 1'b1; //always ready. Can be customized to support waitstate if required.
assign pslverr = 1'b0; //alwyas OKAY. Can be customized to support error response if required.
// LED write signal
//assign write_en = psel & (~penable) & pwrite; // assert for 1st cycle of write transfer
// It is also possible to change the design to perform the write in the 2nd
// APB cycle. E.g.
// assign write_en = psel & penable & pwrite;
// However, if the design generate waitstate, this expression will result
// in write_en being asserted for multiple cycles.
assign write_en = psel & penable & pwrite;
// enable write transfer without wait signal
always @ (posedge pclk or negedge presetn)
begin
if(~presetn)
Reg2LED <= 0;
else if(write_en == 1'b1)
Reg2LED <= pwdata;
else
Reg2LED <= Reg2LED;
end
assign ledNumIn = Reg2LED;
`ifdef ARM_APB_ASSERT_ON
`include "std_ovl_defines.h"
// ------------------------------------------------------------
// Assertions
// ------------------------------------------------------------
// Check error response should not be generated if not selected
assert_never
#(`OVL_ERROR,
`OVL_ASSERT,
"Error! Should not generate error response if not selected")
u_ovl_apb3_eg_slave_response_illegal
(.clk (pclk),
.reset_n (presetn),
.test_expr (pslverr & pready & (~psel))
);
`endif
//------------------------------------------------------------------------------
// module logic end
//------------------------------------------------------------------------------
endmodule

View File

@ -0,0 +1,149 @@
//-----------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from ARM Limited.
//
// (C) COPYRIGHT 2010-2013 ARM Limited.
// ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from ARM Limited.
//
// SVN Information
//
// Checked In : $Date: 2012-07-31 10:47:23 +0100 (Tue, 31 Jul 2012) $
//
// Revision : $Revision: 217027 $
//
// Release Information : Cortex-M System Design Kit-r1p0-00rel0
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Abstract : APB example slave, support AMBA APB3
// slave is always ready and response is always OKAY.
//-----------------------------------------------------------------------------
module cmsdk_apb3_eg_slave_led #(
// parameter for address width
parameter ADDRWIDTH = 12)
(
// IO declaration
input wire PCLK, // pclk
input wire PRESETn, // reset
// apb interface inputs
input wire PSEL,
input wire [ADDRWIDTH-1:0] PADDR,
input wire PENABLE,
input wire PWRITE,
input wire [31:0] PWDATA,
// Engineering-change-order revision bits
input wire [3:0] ECOREVNUM,
// apb interface outputs
output wire [31:0] PRDATA,
output wire PREADY,
output wire PSLVERR,
// LED output
output wire [3:0] ledNumOut
);
//------------------------------------------------------------------------------
//internal wires
//------------------------------------------------------------------------------
// LED module interface signals
wire [31:0] ledNumIn;
//------------------------------------------------------------------------------
// module logic start
//------------------------------------------------------------------------------
// Interface to convert APB signals to simple read and write controls
cmsdk_apb3_eg_slave_interface_led #(.ADDRWIDTH (ADDRWIDTH))
u_apb_eg_slave_interface_led(
.pclk (PCLK), // pclk
.presetn (PRESETn), // reset
.psel (PSEL), // apb interface inputs
.paddr (PADDR),
.penable (PENABLE),
.pwrite (PWRITE),
.pwdata (PWDATA),
.prdata (PRDATA), // apb interface outputs
.pready (PREADY),
.pslverr (PSLVERR),
// LED interface
.ledNumIn (ledNumIn)
);
// LED
custom_apb_led u_custom_apb_led(
.clk (PCLK),
.rst (PRESETn),
.ledNumIn (ledNumIn),
.ledNumOut (ledNumOut)
);
//------------------------------------------------------------------------------
// module logic end
//------------------------------------------------------------------------------
`ifdef ARM_APB_ASSERT_ON
`include "std_ovl_defines.h"
// ------------------------------------------------------------
// Assertions
// ------------------------------------------------------------
// Check the reg_write_en signal generated
assert_implication
#(`OVL_ERROR,
`OVL_ASSERT,
"Error! register write signal was not generated! "
)
u_ovl_apb3_eg_slave_reg_write
(.clk (PCLK),
.reset_n (PRESETn),
.antecedent_expr ( (PSEL & (~PENABLE) & PWRITE) ),
.consequent_expr ( reg_write_en == 1'b1)
);
// Check the reg_read_en signal generated
assert_implication
#(`OVL_ERROR,
`OVL_ASSERT,
"Error! register read signal was not generated! "
)
u_ovl_apb3_eg_slave_reg_read
(.clk (PCLK),
.reset_n (PRESETn),
.antecedent_expr ( (PSEL & (~PENABLE) & (~PWRITE)) ),
.consequent_expr ( reg_read_en == 1'b1)
);
// Check register read and write operation won't assert at the same cycle
assert_never
#(`OVL_ERROR,
`OVL_ASSERT,
"Error! register read and write active at the same cycle!")
u_ovl_apb3_eg_slave_rd_wr_illegal
(.clk (PCLK),
.reset_n (PRESETn),
.test_expr ((reg_write_en & reg_read_en))
);
`endif
endmodule

View File

@ -0,0 +1,29 @@
/* *****************************************************************
* This code is released under the MIT License.
* Copyright (c) 2020 Xuanzhi LIU, Qiao HU, Zongwu HE
*
* For latest version of this code or to issue a problem,
* please visit: <https://github.com/WalkerLau/DetectHumanFaces>
*
* Note: the above information must be kept whenever or wherever the codes are used.
*
* *****************************************************************/
module custom_apb_led(
//led core ports
input wire clk,
input wire rst,
input wire [31:0] ledNumIn,
output reg [3:0] ledNumOut // When high, the LED on board turns off
);
always @ (posedge clk or negedge rst)
begin
if(~rst)
ledNumOut <= 4'b1111;
else if(ledNumIn >= 4'b1111)
ledNumOut <= 4'b0000;
else
ledNumOut <= ~ledNumIn;
end
endmodule

View File

@ -0,0 +1,65 @@
////////////////////////////////////////////////////////////////////////////////
// AHB-Lite Memory Module
////////////////////////////////////////////////////////////////////////////////
module AHB2ROM
#(parameter MEMWIDTH = 15) // Size = 32KB
(
input wire HSEL,
input wire HCLK,
input wire HRESETn,
input wire HREADY,
input wire [31:0] HADDR,
input wire [1:0] HTRANS,
input wire HWRITE,
input wire [2:0] HSIZE,
input wire [31:0] HWDATA,
output wire HREADYOUT,
output reg [31:0] HRDATA
);
assign HREADYOUT = 1'b1; // Always ready
// Memory Array
reg [31:0] memory[0:(2**(MEMWIDTH-2)-1)];
initial begin
(*rom_style="block"*) $readmemh("minSOC.hex", memory);
end
// Registers to store Adress Phase Signals
reg [31:0] hwdata_mask;
reg we;
reg [31:0] buf_hwaddr;
// Sample the Address Phase
always @(posedge HCLK or negedge HRESETn)
begin
if(!HRESETn)
begin
we <= 1'b0;
buf_hwaddr <= 32'h0;
end
else
if(HREADY)
begin
we <= HSEL & HWRITE & HTRANS[1];
buf_hwaddr <= HADDR;
casez (HSIZE[1:0])
2'b1?: hwdata_mask <= 32'hFFFFFFFF; // Word write
2'b01: hwdata_mask <= (32'h0000FFFF << (16 * HADDR[1])); // Halfword write
2'b00: hwdata_mask <= (32'h000000FF << (8 * HADDR[1:0])); // Byte write
endcase
end
end
// Read and Write Memory
always @ (posedge HCLK)
begin
if(we)
memory[buf_hwaddr[MEMWIDTH:2]] <= (HWDATA & hwdata_mask) | (HRDATA & ~hwdata_mask);
HRDATA = memory[HADDR[MEMWIDTH:2]];
end
endmodule

View File

@ -0,0 +1,94 @@
module custom_apb_timer #(
parameter ADDRWIDTH = 12,
parameter CLK_FREQ = 32'd50000000
)
(
//SYSTEM
input wire pclk,
input wire presetn,
output reg [31:0] cp_timerCnt, // ckp
input ui_clk,
output reg [31:0] ui_cnt,
//APB
input wire psel,
input wire [ADDRWIDTH-1:0] paddr,
input wire penable,
input wire pwrite,
input wire [31:0] pwdata,
output reg [31:0] prdata,
output wire pready,
output wire pslverr
);
assign pready = 1'b1; //always ready. Can be customized to support waitstate if required.
assign pslverr = 1'b0; //alwyas OKAY. Can be customized to support error response if required.
assign write_en = psel & penable & pwrite;
assign read_en = psel & penable & (~pwrite);
reg [31:0] cnt;
always @ (posedge pclk or negedge presetn) begin
if(~presetn) begin
cnt <= 32'd0;
end
else if(cnt >= CLK_FREQ/1000 - 1) begin // reset to zero every 1ms
cnt <= 32'd0;
end
else begin
cnt <= cnt + 32'd1;
end
end
reg [31:0] ms_cnt;
always @ (posedge pclk or negedge presetn) begin
if(~presetn)begin
ms_cnt <= 32'd0;
end
else if((write_en == 1'b1) && (pwdata == 32'd1514)) begin
ms_cnt <= 32'd0;
end
else if(cnt == 32'd1) begin
ms_cnt <= ms_cnt + 32'd1;
end
end
always @ (posedge pclk or negedge presetn) begin
if(~presetn)begin
prdata <= 32'd0;
end
else begin
prdata <= ms_cnt;
end
end
always @ (posedge pclk or negedge presetn) begin
if(~presetn)begin
cp_timerCnt <= 32'd0;
end
else if(read_en == 1'b1) begin
cp_timerCnt <= ms_cnt;
end
end
reg [31:0] ui_reg;
always @ (posedge ui_clk or negedge presetn) begin
if(~presetn)begin
ui_reg <= 32'd0;
end
else begin
if(cnt == 32'd1)begin
ui_cnt <= ui_reg;
ui_reg <= 32'd0;
end
else begin
ui_reg <= ui_reg + 32'd1;
end
end
end
endmodule

284
software/CM3DS_MPS2.h Normal file
View File

@ -0,0 +1,284 @@
/**************************************************************************//**
* @file CM3DS_MPS2.h
* @brief CMSIS Cortex-M3 Core Peripheral Access Layer Header File for
* Device CM3DS_MPS2
* @version V3.01
* @date 06. March 2012
*
* @note
* Copyright (C) 2010-2017 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef CM3DS_MPS2_H
#define CM3DS_MPS2_H
#ifdef __cplusplus
extern "C" {
#endif
/** @addtogroup CM3DS_MPS2_Definitions CM3DS_MPS2 Definitions
This file defines all structures and symbols for CM3DS_MPS2:
- registers and bitfields
- peripheral base address
- peripheral ID
- Peripheral definitions
@{
*/
#include <stdint.h>
/******************************************************************************/
/* Processor and Core Peripherals */
/******************************************************************************/
/** @addtogroup CM3DS_MPS2_CMSIS Device CMSIS Definitions
Configuration of the Cortex-M3 Processor and Core Peripherals
@{
*/
/*
* ==========================================================================
* ---------- Interrupt Number Definition -----------------------------------
* ==========================================================================
*/
typedef enum IRQn
{
/****** Cortex-M3 Processor Exceptions Numbers ***************************************************/
NonMaskableInt_IRQn = -14, /*!< 2 Cortex-M3 Non Maskable Interrupt */
HardFault_IRQn = -13, /*!< 3 Cortex-M3 Hard Fault Interrupt */
MemoryManagement_IRQn = -12, /*!< 4 Cortex-M3 Memory Management Interrupt */
BusFault_IRQn = -11, /*!< 5 Cortex-M3 Bus Fault Interrupt */
UsageFault_IRQn = -10, /*!< 6 Cortex-M3 Usage Fault Interrupt */
SVCall_IRQn = -5, /*!< 11 Cortex-M3 SV Call Interrupt */
DebugMonitor_IRQn = -4, /*!< 12 Cortex-M3 Debug Monitor Interrupt */
PendSV_IRQn = -2, /*!< 14 Cortex-M3 Pend SV Interrupt */
SysTick_IRQn = -1, /*!< 15 Cortex-M3 System Tick Interrupt */
/****** CM3DS_MPS2 Specific Interrupt Numbers *******************************************************/
UARTRX_IRQn = 0, /* UART 0 RX and TX Combined Interrupt */
UARTTX_IRQn = 1, /* Undefined */
UARTOVR_IRQn = 2, /* UART 1 RX and TX Combined Interrupt */
ACC_IRQn = 3, /* Hardware Accelerator Return Interrupt */
CAM_IRQn = 4, /* Camera Interrupt */
} IRQn_Type;
/*
* ==========================================================================
* ----------- Processor and Core Peripheral Section ------------------------
* ==========================================================================
*/
/* Configuration of the Cortex-M3 Processor and Core Peripherals */
#define __CM3_REV 0x0201 /*!< Core Revision r2p1 */
#define __NVIC_PRIO_BITS 3 /*!< Number of Bits used for Priority Levels */
#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */
#define __MPU_PRESENT 1 /*!< MPU present or not */
/*@}*/ /* end of group CM3DS_MPS2_CMSIS */
#include "core_cm3.h" /* Cortex-M3 processor and core peripherals */
#include "system_CM3DS.h" /* CM3DS System include file */
/******************************************************************************/
/* Device Specific Peripheral registers structures */
/******************************************************************************/
/** @addtogroup CM3DS_MPS2_Peripherals CM3DS_MPS2 Peripherals
CM3DS_MPS2 Device Specific Peripheral registers structures
@{
*/
#if defined ( __CC_ARM )
#pragma push
#pragma anon_unions
#elif defined(__ICCARM__)
#pragma language=extended
#elif defined(__GNUC__)
/* anonymous unions are enabled by default */
#elif defined(__TMS470__)
/* anonymous unions are enabled by default */
#elif defined(__TASKING__)
#pragma warning 586
#else
#warning Not supported compiler type
#endif
/*------------- Universal Asynchronous Receiver Transmitter (UART) -----------*/
typedef struct
{
__IO uint32_t DATA; /*!< Offset: 0x000 Data Register (R/W) */
__IO uint32_t STATE; /*!< Offset: 0x004 Status Register (R/W) */
__IO uint32_t CTRL; /*!< Offset: 0x008 Control Register (R/W) */
union {
__I uint32_t INTSTATUS; /*!< Offset: 0x00C Interrupt Status Register (R/ ) */
__O uint32_t INTCLEAR; /*!< Offset: 0x00C Interrupt Clear Register ( /W) */
};
__IO uint32_t BAUDDIV; /*!< Offset: 0x010 Baudrate Divider Register (R/W) */
} UART_TypeDef;
/* UART DATA Register Definitions */
#define UART_DATA_Pos 0 /*!< UART_DATA_Pos: DATA Position */
#define UART_DATA_Msk (0xFFul << UART_DATA_Pos) /*!< UART DATA: DATA Mask */
#define UART_STATE_RXOR_Pos 3 /*!< UART STATE: RXOR Position */
#define UART_STATE_RXOR_Msk (0x1ul << UART_STATE_RXOR_Pos) /*!< UART STATE: RXOR Mask */
#define UART_STATE_TXOR_Pos 2 /*!< UART STATE: TXOR Position */
#define UART_STATE_TXOR_Msk (0x1ul << UART_STATE_TXOR_Pos) /*!< UART STATE: TXOR Mask */
#define UART_STATE_RXBF_Pos 1 /*!< UART STATE: RXBF Position */
#define UART_STATE_RXBF_Msk (0x1ul << UART_STATE_RXBF_Pos) /*!< UART STATE: RXBF Mask */
#define UART_STATE_TXBF_Pos 0 /*!< UART STATE: TXBF Position */
#define UART_STATE_TXBF_Msk (0x1ul << UART_STATE_TXBF_Pos ) /*!< UART STATE: TXBF Mask */
#define UART_CTRL_HSTM_Pos 6 /*!< UART CTRL: HSTM Position */
#define UART_CTRL_HSTM_Msk (0x01ul << UART_CTRL_HSTM_Pos) /*!< UART CTRL: HSTM Mask */
#define UART_CTRL_RXORIRQEN_Pos 5 /*!< UART CTRL: RXORIRQEN Position */
#define UART_CTRL_RXORIRQEN_Msk (0x01ul << UART_CTRL_RXORIRQEN_Pos) /*!< UART CTRL: RXORIRQEN Mask */
#define UART_CTRL_TXORIRQEN_Pos 4 /*!< UART CTRL: TXORIRQEN Position */
#define UART_CTRL_TXORIRQEN_Msk (0x01ul << UART_CTRL_TXORIRQEN_Pos) /*!< UART CTRL: TXORIRQEN Mask */
#define UART_CTRL_RXIRQEN_Pos 3 /*!< UART CTRL: RXIRQEN Position */
#define UART_CTRL_RXIRQEN_Msk (0x01ul << UART_CTRL_RXIRQEN_Pos) /*!< UART CTRL: RXIRQEN Mask */
#define UART_CTRL_TXIRQEN_Pos 2 /*!< UART CTRL: TXIRQEN Position */
#define UART_CTRL_TXIRQEN_Msk (0x01ul << UART_CTRL_TXIRQEN_Pos) /*!< UART CTRL: TXIRQEN Mask */
#define UART_CTRL_RXEN_Pos 1 /*!< UART CTRL: RXEN Position */
#define UART_CTRL_RXEN_Msk (0x01ul << UART_CTRL_RXEN_Pos) /*!< UART CTRL: RXEN Mask */
#define UART_CTRL_TXEN_Pos 0 /*!< UART CTRL: TXEN Position */
#define UART_CTRL_TXEN_Msk (0x01ul << UART_CTRL_TXEN_Pos) /*!< UART CTRL: TXEN Mask */
#define UART_INTSTATUS_RXORIRQ_Pos 3 /*!< UART CTRL: RXORIRQ Position */
#define UART_CTRL_RXORIRQ_Msk (0x01ul << UART_INTSTATUS_RXORIRQ_Pos) /*!< UART CTRL: RXORIRQ Mask */
#define UART_CTRL_TXORIRQ_Pos 2 /*!< UART CTRL: TXORIRQ Position */
#define UART_CTRL_TXORIRQ_Msk (0x01ul << UART_CTRL_TXORIRQ_Pos) /*!< UART CTRL: TXORIRQ Mask */
#define UART_CTRL_RXIRQ_Pos 1 /*!< UART CTRL: RXIRQ Position */
#define UART_CTRL_RXIRQ_Msk (0x01ul << UART_CTRL_RXIRQ_Pos) /*!< UART CTRL: RXIRQ Mask */
#define UART_CTRL_TXIRQ_Pos 0 /*!< UART CTRL: TXIRQ Position */
#define UART_CTRL_TXIRQ_Msk (0x01ul << UART_CTRL_TXIRQ_Pos) /*!< UART CTRL: TXIRQ Mask */
#define UART_BAUDDIV_Pos 0 /*!< UART BAUDDIV: BAUDDIV Position */
#define UART_BAUDDIV_Msk (0xFFFFFul << UART_BAUDDIV_Pos) /*!< UART BAUDDIV: BAUDDIV Mask */
/*------------------- FPGA control ----------------------------------------------*/
#if defined ( __CC_ARM )
#pragma anon_unions
#endif
typedef struct
{
volatile uint32_t BTN0;
} APB_BTN_TypeDef;
typedef struct
{
volatile uint32_t LEDS;
} APB_LED_TypeDef;
typedef struct
{
volatile uint32_t TIME;
} APB_TIMER_TypeDef;
typedef struct
{
volatile uint32_t IGNIT;
} APB_IGNITER_TypeDef;
/*------------------ SysTick ------------------------------------------------------*/
typedef struct
{
volatile uint32_t CTRL;
volatile uint32_t LOAD;
volatile uint32_t VALUE;
volatile uint32_t CALIB;
}SysTickType;
/* -------------------- End of section using anonymous unions ------------------- */
#if defined ( __CC_ARM )
#pragma pop
#elif defined(__ICCARM__)
/* leave anonymous unions enabled */
#elif defined(__GNUC__)
/* anonymous unions are enabled by default */
#elif defined(__TMS470__)
/* anonymous unions are enabled by default */
#elif defined(__TASKING__)
#pragma warning restore
#else
#warning Not supported compiler type
#endif
/******************************************************************************/
/* Peripheral memory map */
/******************************************************************************/
/* Peripheral and SRAM base address */
#define CM3DS_MPS2_FLASH_BASE (0x00000000UL) /*!< (FLASH ) Base Address */
#define CM3DS_MPS2_SRAM_BASE (0x20000000UL) /*!< (SRAM ) Base Address */
#define CM3DS_MPS2_PERIPH_BASE (0x40000000UL) /*!< (Peripheral) Base Address */
#define CM3DS_MPS2_RAM_BASE (0x20000000UL)
#define CM3DS_MPS2_APB_BASE (0x40000000UL)
/* SysTick */
#define SysTick_BASE (0xe000e010UL)
/* APB peripherals */
#define APB_LED_BASE (CM3DS_MPS2_APB_BASE + 0x0000UL)
#define APB_BTN_BASE (CM3DS_MPS2_APB_BASE + 0x1000UL)
#define APB_UART_BASE (CM3DS_MPS2_APB_BASE + 0x2000UL)
#define APB_TIME_BASE (CM3DS_MPS2_APB_BASE + 0x3000UL)
#define APB_IGNITER_BASE (CM3DS_MPS2_APB_BASE + 0x4000UL)
/******************************************************************************/
/* Peripheral declaration */
/******************************************************************************/
#define SysTick ((SysTickType *) SysTick_BASE )
#define APB_LED ((APB_LED_TypeDef *) APB_LED_BASE )
#define APB_BTN ((APB_BTN_TypeDef *) APB_BTN_BASE )
#define UART ((UART_TypeDef *) APB_UART_BASE )
#define TIMER ((APB_TIMER_TypeDef *) APB_TIME_BASE )
#define IGNITER ((APB_IGNITER_TypeDef *) APB_IGNITER_BASE )
#ifdef __cplusplus
}
#endif
#endif /* CM3DS_MPS2_H */

View File

@ -0,0 +1,356 @@
/*
*-----------------------------------------------------------------------------
* The confidential and proprietary information contained in this file may
* only be used by a person authorised under and to the extent permitted
* by a subsisting licensing agreement from ARM Limited.
*
* (C) COPYRIGHT 2010-2017 ARM Limited.
* ALL RIGHTS RESERVED
*
* This entire notice must be reproduced on all copies of this file
* and copies of this file may only be made by a person if such person is
* permitted to do so under the terms of a subsisting license agreement
* from ARM Limited.
*
* SVN Information
*
* Checked In : $Date: 2012-05-28 18:02:02 +0100 (Mon, 28 May 2012) $
*
* Revision : $Revision: 210375 $
*
* Release Information : CM3DesignStart-r0p0-02rel0
*-----------------------------------------------------------------------------
*/
/*********************************************************************//******
* @file CM3DS_MPS2_driver.c
* @brief CM3DS_MPS2 Example Device Driver C File
* @version $State:$
* @date $Date: 2012-05-28 18:02:02 +0100 (Mon, 28 May 2012) $
*
******************************************************************************/
#include "CM3DS_MPS2_driver.h"
#include "CM3DS_MPS2.h"
#include <string.h>
/**
*
* @brief Initialises the UART specifying the UART Baud rate divider value and whether the send and recieve functionality is enabled. It also specifies which of the various interrupts are enabled.
*
* @param *uart UART Pointer
* @param divider The value to which the UART baud rate divider is to be set
* @param tx_en Defines whether the UART transmit is to be enabled
* @param rx_en Defines whether the UART receive is to be enabled
* @param tx_irq_en Defines whether the UART transmit buffer full interrupt is to be enabled
* @param rx_irq_en Defines whether the UART receive buffer full interrupt is to be enabled
* @param tx_ovrirq_en Defines whether the UART transmit buffer overrun interrupt is to be enabled
* @param rx_ovrirq_en Defines whether the UART receive buffer overrun interrupt is to be enabled
* @return 1 if initialisation failed, 0 if successful.
*/
uint32_t uart_init( UART_TypeDef *uart, uint32_t divider, uint32_t tx_en,
uint32_t rx_en, uint32_t tx_irq_en, uint32_t rx_irq_en, uint32_t tx_ovrirq_en, uint32_t rx_ovrirq_en)
{
uint32_t new_ctrl=0;
if (tx_en!=0) new_ctrl |= UART_CTRL_TXEN_Msk;
if (rx_en!=0) new_ctrl |= UART_CTRL_RXEN_Msk;
if (tx_irq_en!=0) new_ctrl |= UART_CTRL_TXIRQEN_Msk;
if (rx_irq_en!=0) new_ctrl |= UART_CTRL_RXIRQEN_Msk;
if (tx_ovrirq_en!=0) new_ctrl |= UART_CTRL_TXORIRQEN_Msk;
if (rx_ovrirq_en!=0) new_ctrl |= UART_CTRL_RXORIRQEN_Msk;
uart->CTRL = 0; /* Disable UART when changing configuration */
uart->BAUDDIV = divider;
uart->CTRL = new_ctrl; /* Update CTRL register to new value */
if(( uart->STATE & ( UART_STATE_RXOR_Msk | UART_STATE_TXOR_Msk))) return 1;
else return 0;
}
/**
*
* @param *uart UART Pointer
* @return RxBufferFull
*
* @brief Returns whether the RX buffer is full.
*/
uint32_t uart_GetRxBufferFull( UART_TypeDef * uart)
{
return (( uart->STATE & UART_STATE_RXBF_Msk)>> UART_STATE_RXBF_Pos);
}
/**
*
* @param *uart UART Pointer
* @return TxBufferFull
*
* @brief Returns whether the TX buffer is full.
*/
uint32_t uart_GetTxBufferFull( UART_TypeDef * uart)
{
return (( uart->STATE & UART_STATE_TXBF_Msk)>> UART_STATE_TXBF_Pos);
}
/**
*
* @param *uart UART Pointer
* @param txchar Character to be sent
* @return none
*
* @brief Sends a character to the TX buffer for transmission.
*/
void uart_SendChar( UART_TypeDef * uart, char txchar)
{
while( 1 ){
if(!(uart->STATE & UART_STATE_TXBF_Msk)) break;
};
uart->DATA = (uint32_t)txchar;
}
/**
*
* @param *uart UART Pointer
* @return rxchar
*
* @brief returns the character from the RX buffer which has been received.
*/
char uart_ReceiveChar( UART_TypeDef * uart)
{
while(!( uart->STATE & UART_STATE_RXBF_Msk));
return (char)( uart->DATA);
}
/**
*
* @param *uart UART Pointer
* @return 0 - No overrun
* @return 1 - TX overrun
* @return 2 - RX overrun
* @return 3 - TX & RX overrun
*
* @brief returns the current overrun status of both the RX & TX buffers.
*/
uint32_t uart_GetOverrunStatus( UART_TypeDef *uart)
{
return (( uart->STATE & ( UART_STATE_RXOR_Msk | UART_STATE_TXOR_Msk))>> UART_STATE_TXOR_Pos);
}
/**
*
* @param *uart UART Pointer
* @return 0 - No overrun
* @return 1 - TX overrun
* @return 2 - RX overrun
* @return 3 - TX & RX overrun
*
* @brief Clears the overrun status of both the RX & TX buffers and then returns the current overrun status.
*/
uint32_t uart_ClearOverrunStatus( UART_TypeDef *uart)
{
uart->STATE = ( UART_STATE_RXOR_Msk | UART_STATE_TXOR_Msk);
return (( uart->STATE & ( UART_STATE_RXOR_Msk | UART_STATE_TXOR_Msk))>> UART_STATE_TXOR_Pos);
}
/**
*
* @param *uart UART Pointer
* @return BaudDiv
*
* @brief Returns the current UART Baud rate divider. Note that the Baud rate divider is the difference between the clock frequency and the Baud frequency.
*/
uint32_t uart_GetBaudDivider( UART_TypeDef *uart)
{
return uart->BAUDDIV;
}
/**
*
* @param *uart UART Pointer
* @return TXStatus
*
* @brief Returns the TX interrupt status.
*/
uint32_t uart_GetTxIRQStatus( UART_TypeDef *uart)
{
return (( uart->INTSTATUS & UART_CTRL_TXIRQ_Msk)>> UART_CTRL_TXIRQ_Pos);
}
/**
*
* @param *uart UART Pointer
* @return RXStatus
*
* @brief Returns the RX interrupt status.
*/
uint32_t uart_GetRxIRQStatus( UART_TypeDef *uart)
{
return (( uart->INTSTATUS & UART_CTRL_RXIRQ_Msk)>> UART_CTRL_RXIRQ_Pos);
}
/**
*
* @param *uart UART Pointer
* @return none
*
* @brief Clears the TX buffer full interrupt status.
*/
void uart_ClearTxIRQ( UART_TypeDef *uart)
{
uart->INTCLEAR = UART_CTRL_TXIRQ_Msk;
}
/**
*
* @param *uart UART Pointer
* @return none
*
* @brief Clears the RX interrupt status.
*/
void uart_ClearRxIRQ( UART_TypeDef *uart)
{
uart->INTCLEAR = UART_CTRL_RXIRQ_Msk;
}
void uart_SendString(char *string) {
uint32_t length,i;
length = strlen(string);
for(i = 0;i < length;i++) {
uart_SendChar(UART,string[i]);
}
}
/**************************************SYSTICK********************************/
void Set_SysTick_CTRL(uint32_t ctrl)
{
SysTick->CTRL = ctrl;
}
void Set_SysTick_LOAD(uint32_t load)
{
SysTick->LOAD = load;
}
uint32_t Read_SysTick_VALUE(void)
{
return(SysTick->VALUE);
}
void Set_SysTick_CALIB(uint32_t calib)
{
SysTick->CALIB = calib;
}
void Set_SysTick_VALUE(uint32_t value)
{
SysTick->VALUE = value;
}
uint32_t Timer_Ini(void)
{
SysTick->CTRL = 0;
SysTick->LOAD = 0xffffff;
SysTick->VALUE = 0;
SysTick->CTRL = 0x5;
while(SysTick->VALUE == 0);
return(SysTick->VALUE);
}
uint8_t Timer_Stop(uint32_t *duration_t,uint32_t start_t)
{
uint32_t stop_t;
stop_t = SysTick->VALUE;
if((SysTick->CTRL & 0x10000) == 0)
{
*duration_t = start_t - stop_t;
return(1);
}
else
{
return(0);
}
}
void delay(uint32_t time)
{
Set_SysTick_CTRL(0);
Set_SysTick_LOAD(time);
Set_SysTick_VALUE(0);
Set_SysTick_CTRL(0x7);
__wfi();
}
void SysCountDown(){
Set_SysTick_CTRL(0);
Set_SysTick_LOAD(0xFFFFFF);
Set_SysTick_VALUE(0);
Set_SysTick_CTRL(0x7);
}
uint32_t ReadSystickIRQ(){
return (SysTick->CTRL & 0x10000);
}
/**************************************PUSH_BTN**************************************/
int getPushBtn( APB_BTN_TypeDef* apb_btn){
while (!(apb_btn -> BTN0)) ; // extra while loop to avoid multi-accumulation when long pressing BTN
while (( apb_btn -> BTN0)) ;
return 1;
}
/**************************************LED*******************************************/
void send2LED( uint32_t cnt){
APB_LED_TypeDef* led = APB_LED;
led -> LEDS = cnt;
}
/**************************************TIMER*****************************************/
void rstTime(){
APB_TIMER_TypeDef* time = TIMER;
time -> TIME = 1514;
}
int getTime(){
APB_TIMER_TypeDef* time = TIMER;
return ((int) time -> TIME);
}
/***************************************IGNITER**************************************/
void WaitForReturn(){
__asm volatile ("wfi");
}
void WaitForCam(){
__asm volatile ("wfi");
}
void accStart(){
APB_IGNITER_TypeDef* igniter = IGNITER;
igniter -> IGNIT = 1514;
}
void CamStart(){
APB_IGNITER_TypeDef* igniter = IGNITER;
igniter -> IGNIT = 0xca;
}
int getIndex(){ // 用于读取图像的地址index 该函数与IGNITER没什么关系
APB_IGNITER_TypeDef* igniter = IGNITER;
return ((int) igniter -> IGNIT);
}
void AddrSwitch(){
APB_IGNITER_TypeDef* igniter = IGNITER;
igniter -> IGNIT = 0xda;
}

View File

@ -0,0 +1,145 @@
/*
*-----------------------------------------------------------------------------
* The confidential and proprietary information contained in this file may
* only be used by a person authorised under and to the extent permitted
* by a subsisting licensing agreement from ARM Limited.
*
* (C) COPYRIGHT 2010-2017 ARM Limited.
* ALL RIGHTS RESERVED
*
* This entire notice must be reproduced on all copies of this file
* and copies of this file may only be made by a person if such person is
* permitted to do so under the terms of a subsisting license agreement
* from ARM Limited.
*
* SVN Information
*
* Checked In : $Date: 2012-05-28 18:02:02 +0100 (Mon, 28 May 2012) $
*
* Revision : $Revision: 210375 $
*
* Release Information : CM3DesignStart-r0p0-02rel0
*-----------------------------------------------------------------------------
*/
/*************************************************************************//**
* @file CM3DS_MPS2_driver.h
* @brief CM3DS_MPS2 Driver Header File
* @version $State:$
* @date $Date: 2012-05-28 18:02:02 +0100 (Mon, 28 May 2012) $
*
******************************************************************************/
#ifndef CM3DS_MPS2_DRIVER_H
#define CM3DS_MPS2_DRIVER_H
#include "CM3DS_MPS2.h"
/***********************************uart**************************************/
extern uint32_t uart_init( UART_TypeDef * uart, uint32_t divider, uint32_t tx_en,
uint32_t rx_en, uint32_t tx_irq_en, uint32_t rx_irq_en, uint32_t tx_ovrirq_en, uint32_t rx_ovrirq_en);
/**
* @brief Returns whether the uart RX Buffer is Full.
*/
extern uint32_t uart_GetRxBufferFull( UART_TypeDef * uart);
/**
* @brief Returns whether the uart TX Buffer is Full.
*/
extern uint32_t uart_GetTxBufferFull( UART_TypeDef * uart);
/**
* @brief Sends a character to the uart TX Buffer.
*/
extern void uart_SendChar( UART_TypeDef * uart, char txchar);
/**
* @brief Receives a character from the uart RX Buffer.
*/
extern char uart_ReceiveChar( UART_TypeDef * uart);
/**
* @brief Returns uart Overrun status.
*/
extern uint32_t uart_GetOverrunStatus( UART_TypeDef * uart);
/**
* @brief Clears uart Overrun status Returns new uart Overrun status.
*/
extern uint32_t uart_ClearOverrunStatus( UART_TypeDef * uart);
/**
* @brief Returns uart Baud rate Divider value.
*/
extern uint32_t uart_GetBaudDivider( UART_TypeDef * uart);
/**
* @brief Return uart TX Interrupt Status.
*/
extern uint32_t uart_GetTxIRQStatus( UART_TypeDef * uart);
/**
* @brief Return uart RX Interrupt Status.
*/
extern uint32_t uart_GetRxIRQStatus( UART_TypeDef * uart);
/**
* @brief Clear uart TX Interrupt request.
*/
extern void uart_ClearTxIRQ( UART_TypeDef * uart);
/**
* @brief Clear uart RX Interrupt request.
*/
extern void uart_ClearRxIRQ( UART_TypeDef * uart);
/**************************************SYSTICK********************************/
extern void delay(uint32_t time);
extern void Set_SysTick_CTRL(uint32_t ctrl);
extern void Set_SysTick_LOAD(uint32_t load);
extern uint32_t Read_SysTick_VALUE(void);
extern void Set_SysTick_VALUE(uint32_t value);
extern void Set_SysTick_CALIB(uint32_t calib);
extern uint32_t Timer_Ini(void);
extern uint8_t Timer_Stop(uint32_t *duration_t,uint32_t start_t);
void SysCountDown();
uint32_t ReadSystickIRQ();
void PrintBigInt(int bigInt);
void PrintFloat(float value);
/*************************************PUSH_BTN*********************************/
int getPushBtn( APB_BTN_TypeDef* apb_btn);
/*************************************LED**************************************/
void send2LED( uint32_t cnt);
/*************************************TIMER*************************************/
void rstTime();
int getTime();
/***************************************IGNITER**************************************/
void WaitForReturn();
void accStart();
void WaitForCam();
void CamStart();
int getIndex();
void AddrSwitch();
#endif

13
software/RGBprocess.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef RGBPROCESS_H
#define RGBPROCESS_H
#include <stdint.h>
#define ROWS 480
#define COLS 640
#define RGBsize ROWS*COLS
#define MIN(a,b) ((a) > (b) ? (b) : (a))
void rgb2gray(uint16_t* img, uint8_t* gray);
#endif

55
software/Retarget.c Normal file
View File

@ -0,0 +1,55 @@
/******************************************************************************/
/* RETARGET.C: 'Retarget' layer for target-dependent low level functions */
/******************************************************************************/
/* This file is part of the uVision/ARM development tools. */
/* Copyright (c) 2005 Keil Software. All rights reserved. */
/* This software may only be used under the terms of a valid, current, */
/* end user licence from KEIL for a compatible version of KEIL software */
/* development tools. Nothing else gives you the right to use this software. */
/******************************************************************************/
#include <stdio.h>
#include "CM3DS_MPS2.h"
//#pragma import(__use_no_semihosting_swi)
extern int sendchar(int ch); /* in Serial.c */
extern int getkey(void); /* in Serial.c */
extern long timeval; /* in Time.c */
struct __FILE { int handle; /* Add whatever you need here */ };
FILE __stdout;
FILE __stdin;
int fputc(int ch, FILE *f) {
if(ch == '\n') uart_SendChar(UART,'\r');
uart_SendChar(UART,ch);
return (ch);
}
int fgetc(FILE *f) {
char buf;
buf = uart_ReceiveChar(UART);
uart_SendChar(UART,buf);
if(buf == '\r') buf = '\n';
return (buf);
}
int ferror(FILE *f) {
/* Your implementation of ferror */
return EOF;
}
void _ttywrch(int ch) {
uart_SendChar(UART,ch);
}
void _sys_exit(int return_code) {
while (1); /* endless loop */
}

1627
software/core_cm3.h Normal file

File diff suppressed because it is too large Load Diff

636
software/core_cmFunc.h Normal file
View File

@ -0,0 +1,636 @@
/**************************************************************************//**
* @file core_cmFunc.h
* @brief CMSIS Cortex-M Core Function Access Header File
* @version V3.20
* @date 25. February 2013
*
* @note
*
******************************************************************************/
/* Copyright (c) 2009-2013 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#ifndef __CORE_CMFUNC_H
#define __CORE_CMFUNC_H
/* ########################### Core Function Access ########################### */
/** \ingroup CMSIS_Core_FunctionInterface
\defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/* intrinsic void __enable_irq(); */
/* intrinsic void __disable_irq(); */
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__STATIC_INLINE uint32_t __get_CONTROL(void)
{
register uint32_t __regControl __ASM("control");
return(__regControl);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__STATIC_INLINE void __set_CONTROL(uint32_t control)
{
register uint32_t __regControl __ASM("control");
__regControl = control;
}
/** \brief Get IPSR Register
This function returns the content of the IPSR Register.
\return IPSR Register value
*/
__STATIC_INLINE uint32_t __get_IPSR(void)
{
register uint32_t __regIPSR __ASM("ipsr");
return(__regIPSR);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__STATIC_INLINE uint32_t __get_APSR(void)
{
register uint32_t __regAPSR __ASM("apsr");
return(__regAPSR);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__STATIC_INLINE uint32_t __get_xPSR(void)
{
register uint32_t __regXPSR __ASM("xpsr");
return(__regXPSR);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t __regProcessStackPointer __ASM("psp");
return(__regProcessStackPointer);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
register uint32_t __regProcessStackPointer __ASM("psp");
__regProcessStackPointer = topOfProcStack;
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t __regMainStackPointer __ASM("msp");
return(__regMainStackPointer);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
register uint32_t __regMainStackPointer __ASM("msp");
__regMainStackPointer = topOfMainStack;
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__STATIC_INLINE uint32_t __get_PRIMASK(void)
{
register uint32_t __regPriMask __ASM("primask");
return(__regPriMask);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
register uint32_t __regPriMask __ASM("primask");
__regPriMask = (priMask);
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __enable_fault_irq __enable_fiq
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
#define __disable_fault_irq __disable_fiq
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__STATIC_INLINE uint32_t __get_BASEPRI(void)
{
register uint32_t __regBasePri __ASM("basepri");
return(__regBasePri);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__STATIC_INLINE void __set_BASEPRI(uint32_t basePri)
{
register uint32_t __regBasePri __ASM("basepri");
__regBasePri = (basePri & 0xff);
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
register uint32_t __regFaultMask __ASM("faultmask");
return(__regFaultMask);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
register uint32_t __regFaultMask __ASM("faultmask");
__regFaultMask = (faultMask & (uint32_t)1);
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
return(__regfpscr);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
register uint32_t __regfpscr __ASM("fpscr");
__regfpscr = (fpscr);
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/** \brief Enable IRQ Interrupts
This function enables IRQ interrupts by clearing the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void)
{
__ASM volatile ("cpsie i" : : : "memory");
}
/** \brief Disable IRQ Interrupts
This function disables IRQ interrupts by setting the I-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void)
{
__ASM volatile ("cpsid i" : : : "memory");
}
/** \brief Get Control Register
This function returns the content of the Control Register.
\return Control Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void)
{
uint32_t result;
__ASM volatile ("MRS %0, control" : "=r" (result) );
return(result);
}
/** \brief Set Control Register
This function writes the given value to the Control Register.
\param [in] control Control Register value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control)
{
__ASM volatile ("MSR control, %0" : : "r" (control) : "memory");
}
/** \brief Get IPSR Register
This function returns the content of the IPSR Register.
\return IPSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, ipsr" : "=r" (result) );
return(result);
}
/** \brief Get APSR Register
This function returns the content of the APSR Register.
\return APSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, apsr" : "=r" (result) );
return(result);
}
/** \brief Get xPSR Register
This function returns the content of the xPSR Register.
\return xPSR Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void)
{
uint32_t result;
__ASM volatile ("MRS %0, xpsr" : "=r" (result) );
return(result);
}
/** \brief Get Process Stack Pointer
This function returns the current value of the Process Stack Pointer (PSP).
\return PSP Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, psp\n" : "=r" (result) );
return(result);
}
/** \brief Set Process Stack Pointer
This function assigns the given value to the Process Stack Pointer (PSP).
\param [in] topOfProcStack Process Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack)
{
__ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) : "sp");
}
/** \brief Get Main Stack Pointer
This function returns the current value of the Main Stack Pointer (MSP).
\return MSP Register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void)
{
register uint32_t result;
__ASM volatile ("MRS %0, msp\n" : "=r" (result) );
return(result);
}
/** \brief Set Main Stack Pointer
This function assigns the given value to the Main Stack Pointer (MSP).
\param [in] topOfMainStack Main Stack Pointer value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack)
{
__ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) : "sp");
}
/** \brief Get Priority Mask
This function returns the current state of the priority mask bit from the Priority Mask Register.
\return Priority Mask value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, primask" : "=r" (result) );
return(result);
}
/** \brief Set Priority Mask
This function assigns the given value to the Priority Mask Register.
\param [in] priMask Priority Mask
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask)
{
__ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory");
}
#if (__CORTEX_M >= 0x03)
/** \brief Enable FIQ
This function enables FIQ interrupts by clearing the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void)
{
__ASM volatile ("cpsie f" : : : "memory");
}
/** \brief Disable FIQ
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void)
{
__ASM volatile ("cpsid f" : : : "memory");
}
/** \brief Get Base Priority
This function returns the current value of the Base Priority register.
\return Base Priority register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void)
{
uint32_t result;
__ASM volatile ("MRS %0, basepri_max" : "=r" (result) );
return(result);
}
/** \brief Set Base Priority
This function assigns the given value to the Base Priority register.
\param [in] basePri Base Priority value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value)
{
__ASM volatile ("MSR basepri, %0" : : "r" (value) : "memory");
}
/** \brief Get Fault Mask
This function returns the current value of the Fault Mask register.
\return Fault Mask register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void)
{
uint32_t result;
__ASM volatile ("MRS %0, faultmask" : "=r" (result) );
return(result);
}
/** \brief Set Fault Mask
This function assigns the given value to the Fault Mask register.
\param [in] faultMask Fault Mask value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask)
{
__ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory");
}
#endif /* (__CORTEX_M >= 0x03) */
#if (__CORTEX_M == 0x04)
/** \brief Get FPSCR
This function returns the current value of the Floating Point Status/Control register.
\return Floating Point Status/Control register value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
uint32_t result;
/* Empty asm statement works as a scheduling barrier */
__ASM volatile ("");
__ASM volatile ("VMRS %0, fpscr" : "=r" (result) );
__ASM volatile ("");
return(result);
#else
return(0);
#endif
}
/** \brief Set FPSCR
This function assigns the given value to the Floating Point Status/Control register.
\param [in] fpscr Floating Point Status/Control value to set
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr)
{
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
/* Empty asm statement works as a scheduling barrier */
__ASM volatile ("");
__ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc");
__ASM volatile ("");
#endif
}
#endif /* (__CORTEX_M == 0x04) */
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all instrinsics,
* Including the CMSIS ones.
*/
#endif
/*@} end of CMSIS_Core_RegAccFunctions */
#endif /* __CORE_CMFUNC_H */

688
software/core_cmInstr.h Normal file
View File

@ -0,0 +1,688 @@
/**************************************************************************//**
* @file core_cmInstr.h
* @brief CMSIS Cortex-M Core Instruction Access Header File
* @version V3.20
* @date 05. March 2013
*
* @note
*
******************************************************************************/
/* Copyright (c) 2009-2013 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#ifndef __CORE_CMINSTR_H
#define __CORE_CMINSTR_H
/* ########################## Core Instruction Access ######################### */
/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface
Access to dedicated instructions
@{
*/
#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/
/* ARM armcc specific functions */
#if (__ARMCC_VERSION < 400677)
#error "Please use ARM Compiler Toolchain V4.0.677 or later!"
#endif
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
#define __NOP __nop
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
#define __WFI __wfi
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
#define __WFE __wfe
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
#define __SEV __sev
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
#define __ISB() __isb(0xF)
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
#define __DSB() __dsb(0xF)
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
#define __DMB() __dmb(0xF)
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __REV __rev
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value)
{
rev16 r0, r0
bx lr
}
#endif
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
#ifndef __NO_EMBEDDED_ASM
__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value)
{
revsh r0, r0
bx lr
}
#endif
/** \brief Rotate Right in unsigned value (32 bit)
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
#define __ROR __ror
/** \brief Breakpoint
This function causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __breakpoint(value)
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
#define __RBIT __rbit
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr))
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr))
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr))
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXB(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXH(value, ptr) __strex(value, ptr)
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
#define __STREXW(value, ptr) __strex(value, ptr)
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
#define __CLREX __clrex
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT __ssat
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT __usat
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
#define __CLZ __clz
#endif /* (__CORTEX_M >= 0x03) */
#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/
/* IAR iccarm specific functions */
#include <cmsis_iar.h>
#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/
/* TI CCS specific functions */
#include <cmsis_ccs.h>
#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/
/* GNU gcc specific functions */
/* Define macros for porting to both thumb1 and thumb2.
* For thumb1, use low register (r0-r7), specified by constrant "l"
* Otherwise, use general registers, specified by constrant "r" */
#if defined (__thumb__) && !defined (__thumb2__)
#define __CMSIS_GCC_OUT_REG(r) "=l" (r)
#define __CMSIS_GCC_USE_REG(r) "l" (r)
#else
#define __CMSIS_GCC_OUT_REG(r) "=r" (r)
#define __CMSIS_GCC_USE_REG(r) "r" (r)
#endif
/** \brief No Operation
No Operation does nothing. This instruction can be used for code alignment purposes.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void)
{
__ASM volatile ("nop");
}
/** \brief Wait For Interrupt
Wait For Interrupt is a hint instruction that suspends execution
until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void)
{
__ASM volatile ("wfi");
}
/** \brief Wait For Event
Wait For Event is a hint instruction that permits the processor to enter
a low-power state until one of a number of events occurs.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void)
{
__ASM volatile ("wfe");
}
/** \brief Send Event
Send Event is a hint instruction. It causes an event to be signaled to the CPU.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void)
{
__ASM volatile ("sev");
}
/** \brief Instruction Synchronization Barrier
Instruction Synchronization Barrier flushes the pipeline in the processor,
so that all instructions following the ISB are fetched from cache or
memory, after the instruction has been completed.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void)
{
__ASM volatile ("isb");
}
/** \brief Data Synchronization Barrier
This function acts as a special kind of Data Memory Barrier.
It completes when all explicit memory accesses before this instruction complete.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void)
{
__ASM volatile ("dsb");
}
/** \brief Data Memory Barrier
This function ensures the apparent order of the explicit memory operations before
and after the instruction, without ensuring their completion.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void)
{
__ASM volatile ("dmb");
}
/** \brief Reverse byte order (32 bit)
This function reverses the byte order in integer value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value)
{
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
return __builtin_bswap32(value);
#else
uint32_t result;
__ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
#endif
}
/** \brief Reverse byte order (16 bit)
This function reverses the byte order in two unsigned short values.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value)
{
uint32_t result;
__ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
}
/** \brief Reverse byte order in signed short value
This function reverses the byte order in a signed short value with sign extension to integer.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value)
{
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
return (short)__builtin_bswap16(value);
#else
uint32_t result;
__ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) );
return(result);
#endif
}
/** \brief Rotate Right in unsigned value (32 bit)
This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits.
\param [in] value Value to rotate
\param [in] value Number of Bits to rotate
\return Rotated value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2)
{
return (op1 >> op2) | (op1 << (32 - op2));
}
/** \brief Breakpoint
This function causes the processor to enter Debug state.
Debug tools can use this to investigate system state when the instruction at a particular address is reached.
\param [in] value is ignored by the processor.
If required, a debugger can use it to store additional information about the breakpoint.
*/
#define __BKPT(value) __ASM volatile ("bkpt "#value)
#if (__CORTEX_M >= 0x03)
/** \brief Reverse bit order of value
This function reverses the bit order of the given value.
\param [in] value Value to reverse
\return Reversed value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value)
{
uint32_t result;
__ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
/** \brief LDR Exclusive (8 bit)
This function performs a exclusive LDR command for 8 bit value.
\param [in] ptr Pointer to data
\return value of type uint8_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
return(result);
}
/** \brief LDR Exclusive (16 bit)
This function performs a exclusive LDR command for 16 bit values.
\param [in] ptr Pointer to data
\return value of type uint16_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr)
{
uint32_t result;
#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8)
__ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) );
#else
/* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not
accepted by assembler. So has to use following less efficient pattern.
*/
__ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" );
#endif
return(result);
}
/** \brief LDR Exclusive (32 bit)
This function performs a exclusive LDR command for 32 bit values.
\param [in] ptr Pointer to data
\return value of type uint32_t at (*ptr)
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) );
return(result);
}
/** \brief STR Exclusive (8 bit)
This function performs a exclusive STR command for 8 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr)
{
uint32_t result;
__ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
return(result);
}
/** \brief STR Exclusive (16 bit)
This function performs a exclusive STR command for 16 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr)
{
uint32_t result;
__ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
return(result);
}
/** \brief STR Exclusive (32 bit)
This function performs a exclusive STR command for 32 bit values.
\param [in] value Value to store
\param [in] ptr Pointer to location
\return 0 Function succeeded
\return 1 Function failed
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr)
{
uint32_t result;
__ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) );
return(result);
}
/** \brief Remove the exclusive lock
This function removes the exclusive lock which is created by LDREX.
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void)
{
__ASM volatile ("clrex" ::: "memory");
}
/** \brief Signed Saturate
This function saturates a signed value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (1..32)
\return Saturated value
*/
#define __SSAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Unsigned Saturate
This function saturates an unsigned value.
\param [in] value Value to be saturated
\param [in] sat Bit position to saturate to (0..31)
\return Saturated value
*/
#define __USAT(ARG1,ARG2) \
({ \
uint32_t __RES, __ARG1 = (ARG1); \
__ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \
__RES; \
})
/** \brief Count leading zeros
This function counts the number of leading zeros of a data value.
\param [in] value Value to count the leading zeros
\return number of leading zeros in value
*/
__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value)
{
uint32_t result;
__ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) );
return(result);
}
#endif /* (__CORTEX_M >= 0x03) */
#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/
/* TASKING carm specific functions */
/*
* The CMSIS functions have been implemented as intrinsics in the compiler.
* Please use "carm -?i" to get an up to date list of all intrinsics,
* Including the CMSIS ones.
*/
#endif
/*@}*/ /* end of group CMSIS_Core_InstructionInterface */
#endif /* __CORE_CMINSTR_H */

59
software/handler.c Normal file
View File

@ -0,0 +1,59 @@
#include "CM3DS_MPS2.h"
void NMIHandler(void) {
;
}
void HardFaultHandler(void) {
;
}
void MemManageHandler(void) {
;
}
void BusFaultHandler(void) {
;
}
void UsageFaultHandler(void) {
;
}
void SVCHandler(void) {
;
}
void DebugMonHandler(void) {
;
}
void PendSVHandler(void) {
;
}
void SysTickHandler(void) {
Set_SysTick_CTRL(0);
SCB->ICSR = SCB->ICSR | (1 << 25);
}
void UARTRXHandler(void) {
;
}
void UARTTXHandler(void) {
;
}
void UARTOVRHandler(void) {
;
}
void ACCHandler(void) {
;
}
void CAMHandler(void) {
;
}

184
software/main.c Normal file
View File

@ -0,0 +1,184 @@
/* *****************************************************************
* This code is released under the MIT License.
* Copyright (c) 2020 Xuanzhi LIU, Qiao HU, Zongwu HE
*
* For latest version of this code or to issue a problem,
* please visit: <https://github.com/WalkerLau/DetectHumanFaces>
*
* Note: the above information must be kept whenever or wherever the codes are used.
*
* *****************************************************************/
#include <stdio.h>
#include <stdint.h>
//
#include "./CM3DS_MPS2.h"
#include "./CM3DS_MPS2_driver.h"
#include "./picornt.h"
#include "./RGBprocess.h"
void PrintBigInt(int bigInt) {
int thousand, hundred, ten, one;
int tem1, tem2, tem3, tem4;
thousand = (bigInt / 1000) % 10;
tem1 = thousand * 1000;
hundred = ((bigInt - tem1) / 100) % 10;
tem2 = hundred * 100;
ten = ((bigInt - tem1 - tem2) / 10) % 10;
tem3 = ten * 10;
one = bigInt - tem1 - tem2 - tem3;
if (bigInt > 9999 || bigInt < 0) {
printf("Error!!! PrintBigInt out of range, should be in [0, 9999]\n");
}
else if ((thousand != 0)) {
printf("%d%d%d%d", thousand, hundred, ten, one);
}
else if ((thousand == 0) && (hundred != 0)) {
printf("%d%d%d", hundred, ten, one);
}
else if ((thousand == 0) && (hundred == 0) && (ten != 0)) {
printf("%d%d", ten, one);
}
else if ((thousand == 0) && (hundred == 0) && (ten == 0) && (one != 0)) {
printf("%d", one);
}
else {
printf("0");
}
}
void PrintFloat(float value)
{
int tmp, tmp1, tmp2;
tmp = (int)value;
tmp1 = (int)((value - tmp) * 10) % 10;
tmp2 = (int)((value - tmp) * 100) % 10;
PrintBigInt(tmp);
printf(".%d%d", tmp1, tmp2);
}
void process_image(volatile uint16_t* frame, int draw, int minsize, float angle, float scalefactor, float stridefactor, int noclustering, void* cascade)
{
int i, j;
float t;
uint16_t* pixels = frame;
int nrows, ncols, ldim;
#define MAXNDETECTIONS 1024
int ndetections;
float rcsq[4*MAXNDETECTIONS];
nrows = ROWS;
ncols = COLS;
ldim = COLS; // 图像的一行数据的字节数
//chg 计时开始
//int durTime;
//chg del: rstTime();
//
//int findObjectsTime; //chg
//rstTime(); //chg
ndetections = find_objects(rcsq, MAXNDETECTIONS, cascade, angle, pixels, nrows, ncols, ldim, scalefactor, stridefactor, minsize, MIN(nrows, ncols));
//findObjectsTime = getTime(); //chg
//printf("find objects time = "); PrintBigInt(findObjectsTime); printf(" ms\n"); //chg
// cluster_detections函数用于处理重叠的目标把它们合并为一个。
ndetections = cluster_detections(rcsq, ndetections);
//chg del: durTime = getTime();
//画框框
int x, y, side;
int p1, p2, p3, p4;
if (ndetections) {
for (int i = 0; i < ndetections; i++) {
x = (int)rcsq[4 * i + 1];
y = (int)rcsq[4 * i + 0];
side = (int)(rcsq[4 * i + 2] / 2);
p1 = (x - side) + (y - 1 - side) * COLS;
p2 = (x + side) + (y - 1 - side) * COLS;
p3 = (x - side) + (y - 1 + side) * COLS;
for (int j = 0; j < 2 * side; j++) {
frame[p1 + j] = 0xF800;
frame[p2 + j * COLS] = 0xF800;
frame[p1 + j * COLS] = 0xF800;
frame[p3 + j] = 0xF800;
}
}
}
AddrSwitch();
send2LED(ndetections);
printf("/////////////////////////////////////////////\n");
printf("number of faces = %d\n", ndetections);
//chg del: printf("detection time of this frame = "); PrintBigInt(durTime); printf(" ms\n");
if (ndetections) {
for (int i = 0; i < ndetections; i++) {
printf("--------------------------\n");
printf("face %d info:\n", i + 1);
printf(" location = ("); PrintFloat(rcsq[4 * i + 1]); printf(", "); PrintFloat(rcsq[4 * i + 0]);
printf(")\n scale = "); PrintFloat(rcsq[4 * i + 2]);
printf("\n");
}
}
}
/***************************
* param1 = executefile, param2 = cascadefile, param3 = picturefile
***************************/
int main(void){
printf("******************\n");
printf("cortex-m3 startup!\n");
printf("******************\n");
send2LED(0x01);
delay(50000000);
send2LED(0x03);
delay(50000000);
send2LED(0x07);
delay(50000000);
send2LED(0x0f);
delay(50000000);
send2LED(0x00);
// read cascade file from DDR
volatile void* cascade = (void*) 0x28000000UL;
volatile uint8_t* img;
int minsize = 128;
int maxsize = 400;
float angle = 0.0f;
float scalefactor = 1.2f;
float stridefactor = 0.18f;
int noclustering = 0;
//
int processImageTime; //chg
int pixelAddrIndex;
while(1){
CamStart();
WaitForCam();
rstTime(); //chg
pixelAddrIndex = getIndex();
if(1 == pixelAddrIndex){
img = 0x2bc00000UL;
}
else if(0 == pixelAddrIndex){
img = 0x2be00000UL;
}
process_image((uint16_t*)img, 1, minsize, angle, scalefactor, stridefactor, noclustering, cascade);
processImageTime = getTime(); //chg
printf("process Image Time = "); PrintBigInt(processImageTime); printf(" ms\n"); //chg
}
return 0;
}

463
software/picornt.c Normal file
View File

@ -0,0 +1,463 @@
/* *****************************************************************
* This code is released under the MIT License.
* Copyright (c) 2020 Xuanzhi LIU, Qiao HU, Zongwu HE
*
* For latest version of this code or to issue a problem,
* please visit: <https://github.com/WalkerLau/DetectHumanFaces>
*
* Note: the above information must be kept whenever or wherever the codes are used.
*
* *****************************************************************/
#define MAX(a, b) ((a)>(b)?(a):(b))
#define MIN(a, b) ((a)<(b)?(a):(b))
#include <stdint.h>
#include <stdio.h>
#include "./CM3DS_MPS2_driver.h"
/*
*/
/*************************************
* :
* ntrees棵树6confidence
* confidence不断进行累加
* confidence
*
* *** o confidence
* *** r/c/s row/column/scale
* *** vppixels
*************************************/
int run_cascade(void* cascade, float* o, int r, int c, int s, void* vppixels, int nrows, int ncols, int ldim)
{
int* rcs = (int*) 0x28400000UL;
rcs[0] = (int)r; rcs[1] = (int)c; rcs[2] = (int)s;
accStart();
WaitForReturn();
uint32_t* return_p = 0x2840000cUL;
float* o_p = 0x28400010UL;
*o = *o_p;
return *return_p;
// ////////////////////////////////////////////////////////////////////////////////////////////////////////
// int i, j, idx;
//
// uint8_t* pixels;
//
// int tdepth, ntrees, offset;
//
// int8_t* ptree;
// int8_t* tcodes;
// float* lut;
// float thr;
//
// //
// pixels = (uint8_t*)vppixels;
//
// // cascade参数文件的头信息以32位int形式储存
// tdepth = ((int*)cascade)[2]; // 树的深度每棵树的深度都是6
// ntrees = ((int*)cascade)[3]; // cascade中树的总数参数中一共有468棵树的数据
//
// // 乘以256是因为后面的tcodes用的是int8_t类型数值范围较大后面还会除以256来恢复
// r = r*256;
// c = c*256;
//
// // 以(c,r)点为中心探测边长为s的正方形检测区是否超出原图边界
// if (((r + (s << 7)) >> 8) >= nrows || ((r - (s << 7)) >> 8) < 0 || ((c + (s << 7)) >> 8) >= ncols || ((c - (s << 7)) >> 8) < 0)
// return -1;
//
// // ptree的offset值每棵树之间的地址间隔为offset
// offset = ((1<<tdepth)-1)*sizeof(int32_t) + (1<<tdepth)*sizeof(float) + 1*sizeof(float);
// /******************************************************
// * ptree是指向树的指针单位是8位int类型
// * 每棵树的数据由tcodes、lut、thr三个部件组成
// * ** tcodes占((1<<tdepth)-1)*sizeof(int32_t)):决定了要对比强度的像素的移动轨迹
// * ** lut占(1<<tdepth)*sizeof(float)储存了这棵树所有可能决策结果对应的confidence
// * ** thr占sizeof(float)confidence阈值
// * 初始化ptree加了2个float和2个int类型的offset后才指向树证明cascade参数文件头信息一开始是2个int和两个float数据
// ******************************************************/
// ptree = (int8_t*)cascade + 2*sizeof(float) + 2*sizeof(int);
//
// *o = 0.0f;
//
// for(i=0; i<ntrees; ++i)
// {
// //
// tcodes = ptree - 4; // -4是因为后面的idx初始化为1使得tcodes[4*idx]是从tcodes[0]开始的
// lut = (float*)(ptree + ((1<<tdepth)-1)*sizeof(int32_t)); // 1<<tdepth 巧妙地扁平化了层级结构的二元决策树有点像神经网络的receptive field
// thr = *(float*)(ptree + ((1<<tdepth)-1)*sizeof(int32_t) + (1<<tdepth)*sizeof(float));
//
// //
// idx = 1;
//
// // 一棵树沿深度方向的二元决策,决策判据是这棵树各层所指定图像位置的强度
// // 经过tdepth6层决策后得到最终所落在的位置是 idx-(1<<tdepth)
// // 减去(1<<tdepth)是因为(1<<tdepth)是一个偏移值使得对于最终的lut[n]有n在整数区间[0,63]的范围内
// // tcodes[4*idx+0]中的4是因为tcodes地址的数据int_8类型每4个为一组
// for (j = 0; j < tdepth; ++j)
// idx = 2 * idx + (pixels[((r + tcodes[4 * idx + 0] * s) >> 8) * ldim + ((c + tcodes[4 * idx + 1] * s) >> 8)]
// <= pixels[((r + tcodes[4 * idx + 2] * s) >> 8) * ldim + ((c + tcodes[4 * idx + 3] * s) >> 8)]);
//
// // 论文说对每棵树的output决策confidence进行累加并threshold
// *o = *o + lut[idx-(1<<tdepth)];
//
// //
// if(*o<=thr)
// return -1; // confidence低于阈值的目标将马上被排除run_cascade返回-1
// else
// ptree = ptree + offset; // 高于阈值的目标可以继续
// }
//
// //
// *o = *o - thr;
//
// return +1;
}
int run_rotated_cascade(void* cascade, float* o, int r, int c, int s, float a, void* vppixels, int nrows, int ncols, int ldim)
{
//
int i, j, idx;
uint8_t* pixels;
int tdepth, ntrees, offset;
int8_t* ptree;
int8_t* tcodes;
float* lut;
float thr;
static int qcostable[32+1] = {256, 251, 236, 212, 181, 142, 97, 49, 0, -49, -97, -142, -181, -212, -236, -251, -256, -251, -236, -212, -181, -142, -97, -49, 0, 49, 97, 142, 181, 212, 236, 251, 256};
static int qsintable[32+1] = {0, 49, 97, 142, 181, 212, 236, 251, 256, 251, 236, 212, 181, 142, 97, 49, 0, -49, -97, -142, -181, -212, -236, -251, -256, -251, -236, -212, -181, -142, -97, -49, 0};
//
pixels = (uint8_t*)vppixels;
//
tdepth = ((int*)cascade)[2];
ntrees = ((int*)cascade)[3];
//
r = r*65536;
c = c*65536;
if( (r+46341*s)/65536>=nrows || (r-46341*s)/65536<0 || (c+46341*s)/65536>=ncols || (c-46341*s)/65536<0 )
return -1;
//
offset = ((1<<tdepth)-1)*sizeof(int32_t) + (1<<tdepth)*sizeof(float) + 1*sizeof(float);
ptree = (int8_t*)cascade + 2*sizeof(float) + 2*sizeof(int);
*o = 0.0f;
int qsin = s*qsintable[(int)(32*a)]; //s*(int)(256.0f*sinf(2*M_PI*a));
int qcos = s*qcostable[(int)(32*a)]; //s*(int)(256.0f*cosf(2*M_PI*a));
for(i=0; i<ntrees; ++i)
{
//
tcodes = ptree - 4;
lut = (float*)(ptree + ((1<<tdepth)-1)*sizeof(int32_t));
thr = *(float*)(ptree + ((1<<tdepth)-1)*sizeof(int32_t) + (1<<tdepth)*sizeof(float));
//
idx = 1;
for(j=0; j<tdepth; ++j)
{
int r1, c1, r2, c2;
//
r1 = (r + qcos*tcodes[4*idx+0] - qsin*tcodes[4*idx+1])/65536;
c1 = (c + qsin*tcodes[4*idx+0] + qcos*tcodes[4*idx+1])/65536;
r2 = (r + qcos*tcodes[4*idx+2] - qsin*tcodes[4*idx+3])/65536;
c2 = (c + qsin*tcodes[4*idx+2] + qcos*tcodes[4*idx+3])/65536;
//
idx = 2*idx + (pixels[r1*ldim+c1]<=pixels[r2*ldim+c2]);
}
*o = *o + lut[idx-(1<<tdepth)];
//
if(*o<=thr)
return -1;
else
ptree = ptree + offset;
}
//
*o = *o - thr;
return +1;
}
/***********************************
* rcsq储存并返回所检测到的有效目标的位置confidence
* maxndetections
* cascade是级联分类器参数文件
* pixels是摄像头拍到的整张图片
*
***********************************/
int find_objects
(
float rcsq[], int maxndetections,
void* cascade, float angle, // * `angle` is a number between 0 and 1 that determines the counterclockwise in-plane rotation of the cascade: 0.0f corresponds to 0 radians and 1.0f corresponds to 2*pi radians
void* pixels, int nrows, int ncols, int ldim,
float scalefactor, float stridefactor, float minsize, float maxsize
)
{
float s; // 目标检测区(正方形)的边长
int ndetections; // number of detections检测到的目标数量
//
ndetections = 0;
s = minsize;
int totalTime = 0; //chg
int checkTime; //chg
int iter = 0; //chg
int* rcs1 = (int*) 0x28400000UL;
int* rcs2 = (int*) 0x28400010UL;
float* q1 = 0x28500000UL;
float* q2 = 0x28500010UL;
uint32_t* t1 = 0x28500004UL;
uint32_t* t2 = 0x28500014UL;
while(s<=maxsize)
{
float r;
float c1, c2;
float dr, dc;
dr = dc = MAX(stridefactor*s, 1.0f);
// 将级联分类器在原图上进行横轴、纵轴移窗
for(r=s/2+1; r<=nrows-s/2-1; r+=dr){
for(c1=s/2+1; c1<=ncols-s/2-1; c1+=2*dc){
*t1 = 0; *t2 = 0;
c2 = c1 + dc;
rcs1[0] = r; rcs1[1] = c1; rcs1[2] = s;
rcs2[0] = r; rcs2[1] = c2; rcs2[2] = s;
accStart();
WaitForReturn();
// if(0.0f==angle){
// //rstTime(); //chg
// t = run_cascade(cascade, &q, r, c, s, pixels, nrows, ncols, ldim);
// //checkTime = getTime(); //chg
// //totalTime += checkTime; //chg
// //iter++; //chg
// }
// else
// t = run_rotated_cascade(cascade, &q, r, c, s, angle, pixels, nrows, ncols, ldim);
if(1==*t1) // t=1意味着输入到cascade分类器的是有效目标
{
if(ndetections < maxndetections)
{
rcsq[4*ndetections+0] = r; // 圆心的y坐标行号
rcsq[4*ndetections+1] = c1; // 圆心的x坐标列号
rcsq[4*ndetections+2] = s; // 目标区域的scale即圆的直径
rcsq[4*ndetections+3] = *q1; // confidence
//
++ndetections;
}
}
if(c2 <= ncols-s/2-1){
if(1==*t2) // t=1意味着输入到cascade分类器的是有效目标
{
if(ndetections < maxndetections)
{
rcsq[4*ndetections+0] = r; // 圆心的y坐标行号
rcsq[4*ndetections+1] = c2; // 圆心的x坐标列号
rcsq[4*ndetections+2] = s; // 目标区域的scale即圆的直径
rcsq[4*ndetections+3] = *q2; // confidence
//
++ndetections;
}
}
}
}
}
// 一轮横、纵移窗后,改变检测区大小,继续移窗
s = scalefactor*s;
}
//printf("time for running run_cascade is: "); PrintFloat(totalTime/iter); printf("\n"); //chg
//printf("iter is: "); PrintBigInt(iter); printf("\n");
//
return ndetections;
}
/*
*/
float get_overlap(float r1, float c1, float s1, float r2, float c2, float s2)
{
float overr, overc;
//
overr = MAX(0, MIN(r1+s1/2, r2+s2/2) - MAX(r1-s1/2, r2-s2/2));
overc = MAX(0, MIN(c1+s1/2, c2+s2/2) - MAX(c1-s1/2, c2-s2/2));
//
return overr*overc/(s1*s1+s2*s2-overr*overc);
}
void ccdfs(int a[], int i, float rcsq[], int n)
{
int j;
//
for(j=0; j<n; ++j)
if(a[j]==0 && get_overlap(rcsq[4*i+0], rcsq[4*i+1], rcsq[4*i+2], rcsq[4*j+0], rcsq[4*j+1], rcsq[4*j+2])>0.3f)
{
//
a[j] = a[i];
//
ccdfs(a, j, rcsq, n);
}
}
int find_connected_components(int a[], float rcsq[], int n)
{
int i, cc;
//
if(!n)
return 0;
//
for(i=0; i<n; ++i)
a[i] = 0;
//
cc = 1;
for(i=0; i<n; ++i)
if(a[i] == 0)
{
//
a[i] = cc;
//
ccdfs(a, i, rcsq, n);
//
++cc;
}
//
return cc - 1; // number of connected components
}
// cluster_detections函数用于处理重叠的目标把它们合并为一个。
int cluster_detections(float rcsq[], int n)
{
int idx, ncc, cc;
int a[4096];
//
ncc = find_connected_components(a, rcsq, n);
if(!ncc)
return 0;
//
idx = 0;
for(cc=1; cc<=ncc; ++cc)
{
int i, k;
float sumqs=0.0f, sumrs=0.0f, sumcs=0.0f, sumss=0.0f;
//
k = 0;
for(i=0; i<n; ++i)
if(a[i] == cc)
{
sumrs += rcsq[4*i+0];
sumcs += rcsq[4*i+1];
sumss += rcsq[4*i+2];
sumqs += rcsq[4*i+3];
++k;
}
//
rcsq[4*idx+0] = sumrs/k;
rcsq[4*idx+1] = sumcs/k;
rcsq[4*idx+2] = sumss/k;;
rcsq[4*idx+3] = sumqs; // accumulated confidence measure
//
++idx;
}
//
return idx;
}
/*
*/
int update_memory
(
int* slot,
float memory[], int counts[], int nmemslots, int maxslotsize,
float rcsq[], int ndets, int maxndets
)
{
int i, j;
//
counts[*slot] = ndets;
for(i=0; i<counts[*slot]; ++i)
{
memory[*slot*4*maxslotsize + 4*i + 0] = rcsq[4*i + 0];
memory[*slot*4*maxslotsize + 4*i + 1] = rcsq[4*i + 1];
memory[*slot*4*maxslotsize + 4*i + 2] = rcsq[4*i + 2];
memory[*slot*4*maxslotsize + 4*i + 3] = rcsq[4*i + 3];
}
*slot = (*slot + 1)%nmemslots;
//
ndets = 0;
for(i=0; i<nmemslots; ++i)
for(j=0; j<counts[i]; ++j)
{
if(ndets >= maxndets)
return ndets;
rcsq[4*ndets + 0] = memory[i*4*maxslotsize + 4*j + 0];
rcsq[4*ndets + 1] = memory[i*4*maxslotsize + 4*j + 1];
rcsq[4*ndets + 2] = memory[i*4*maxslotsize + 4*j + 2];
rcsq[4*ndets + 3] = memory[i*4*maxslotsize + 4*j + 3];
++ndets;
}
return ndets;
}

31
software/picornt.h Normal file
View File

@ -0,0 +1,31 @@
/*
* This code is released under the MIT License.
* Copyright (c) 2013 Nenad Markus
*/
#pragma once
/*
*/
// * `angle` is a number between 0 and 1 that determines the counterclockwise in-plane rotation of the cascade:
// 0.0f corresponds to 0 radians and 1.0f corresponds to 2*pi radians
int find_objects
(
float rcsq[], int maxndetections,
void* cascade, float angle,
void* pixels, int nrows, int ncols, int ldim,
float scalefactor, float stridefactor, float minsize, float maxsize
);
int cluster_detections(float rcsq[], int n);
int update_memory
(
int* slot,
float memory[], int counts[], int nmemslots, int maxslotsize,
float rcsq[], int ndets, int maxndets
);

250
software/startup_CM3DS.s Normal file
View File

@ -0,0 +1,250 @@
;/**************************************************************************//**
; * @file startup_CM3DS_MPS2.s
; * @brief CMSIS Cortex-M3 Core Device Startup File for
; * Device CM3DS_MPS2
; * @version V3.01
; * @date 06. March 2012
; *
; * @note
; * Copyright (C) 2012,2017 ARM Limited. All rights reserved.
; *
; * @par
; * ARM Limited (ARM) is supplying this software for use with Cortex-M
; * processor based microcontrollers. This file can be freely distributed
; * within development tools that are supporting such ARM based processors.
; *
; * @par
; * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
; * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
; * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
; * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
; * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
; *
; ******************************************************************************/
;/*
;//-------- <<< Use Configuration Wizard in Context Menu >>> ------------------
;*/
; <h> Stack Configuration
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Stack_Size EQU 0x00100000
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
; <h> Heap Configuration
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
; </h>
Heap_Size EQU 0x00100000
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
PRESERVE8
THUMB
; Vector Table Mapped to Address 0 at Reset
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD MemManage_Handler ; MPU Fault Handler
DCD BusFault_Handler ; Bus Fault Handler
DCD UsageFault_Handler ; Usage Fault Handler
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall Handler
DCD DebugMon_Handler ; Debug Monitor Handler
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV Handler
DCD SysTick_Handler ; SysTick Handler
; External Interrupts
DCD UARTRX_Handler ; UART RX Handler
DCD UARTTX_Handler ; UART TX Handler
DCD UARTOVR_Handler ; UART RX and TX OVERRIDE Handler
DCD ACC_Handler ; Hardware Accelerator Return Handler
DCD CAM_Handler ; CAMERA Handler
__Vectors_End
__Vectors_Size EQU __Vectors_End - __Vectors
AREA |.text|, CODE, READONLY
; Reset Handler
Reset_Handler PROC
EXPORT Reset_Handler [WEAK]
IMPORT SystemInit
IMPORT main
LDR R0, =SystemInit
BLX R0
LDR R0, =main
BX R0
ENDP
; Dummy Exception Handlers (infinite loops which can be modified)
NMI_Handler PROC
EXPORT NMI_Handler [WEAK]
IMPORT NMIHandler
PUSH {LR}
BL NMIHandler
POP {PC}
ENDP
HardFault_Handler PROC
EXPORT HardFault_Handler [WEAK]
IMPORT HardFaultHandler
PUSH {LR}
BL HardFaultHandler
POP {PC}
ENDP
MemManage_Handler PROC
EXPORT MemManage_Handler [WEAK]
IMPORT MemManageHandler
PUSH {LR}
BL MemManageHandler
POP {PC}
ENDP
BusFault_Handler PROC
EXPORT BusFault_Handler [WEAK]
IMPORT BusFaultHandler
PUSH {LR}
BL BusFaultHandler
POP {PC}
ENDP
UsageFault_Handler PROC
EXPORT UsageFault_Handler [WEAK]
IMPORT UsageFaultHandler
PUSH {LR}
BL UsageFaultHandler
POP {PC}
ENDP
SVC_Handler PROC
EXPORT SVC_Handler [WEAK]
IMPORT SVCHandler
PUSH {LR}
BL SVCHandler
POP {PC}
ENDP
DebugMon_Handler PROC
EXPORT DebugMon_Handler [WEAK]
IMPORT DebugMonHandler
PUSH {LR}
BL DebugMonHandler
POP {PC}
ENDP
PendSV_Handler PROC
EXPORT PendSV_Handler [WEAK]
IMPORT PendSVHandler
PUSH {LR}
BL PendSVHandler
POP {PC}
ENDP
SysTick_Handler PROC
EXPORT SysTick_Handler [WEAK]
IMPORT SysTickHandler
PUSH {LR}
BL SysTickHandler
POP {PC}
ENDP
UARTRX_Handler PROC
EXPORT UARTRX_Handler [WEAK]
IMPORT UARTRXHandler
PUSH {LR}
BL UARTRXHandler
POP {PC}
ENDP
UARTTX_Handler PROC
EXPORT UARTTX_Handler [WEAK]
IMPORT UARTTXHandler
PUSH {LR}
BL UARTTXHandler
POP {PC}
ENDP
UARTOVR_Handler PROC
EXPORT UARTOVR_Handler [WEAK]
IMPORT UARTOVRHandler
PUSH {LR}
BL UARTOVRHandler
POP {PC}
ENDP
ACC_Handler PROC
EXPORT ACC_Handler [WEAK]
IMPORT ACCHandler
PUSH {LR}
BL ACCHandler
POP {PC}
ENDP
CAM_Handler PROC
EXPORT CAM_Handler [WEAK]
IMPORT CAMHandler
PUSH {LR}
BL CAMHandler
POP {PC}
ENDP
ALIGN
; User Initial Stack & Heap
IF :DEF:__MICROLIB
EXPORT __initial_sp
EXPORT __heap_base
EXPORT __heap_limit
ELSE
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap PROC
LDR R0, = Heap_Mem
LDR R1, =(Stack_Mem + Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ENDP
ALIGN
ENDIF
END

97
software/system_CM3DS.c Normal file
View File

@ -0,0 +1,97 @@
/**************************************************************************//**
* @file system_CM3DS_MPS2.c
* @brief CMSIS Device System Source File for
* CM3DS_MPS2 M3 Device
* @version V3.02
* @date 15. November 2013
*
* @note
*
******************************************************************************/
/* Copyright (c) 2011-2013 ARM LIMITED
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
- Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
- Neither the name of ARM nor the names of its contributors may be used
to endorse or promote products derived from this software without
specific prior written permission.
*
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------*/
#include "CM3DS_MPS2.h"
/*----------------------------------------------------------------------------
Define clocks
*----------------------------------------------------------------------------*/
#define __XTAL (50000000UL) /* Oscillator frequency */
#define __SYSTEM_CLOCK (__XTAL)
/*----------------------------------------------------------------------------
Clock Variable definitions
*----------------------------------------------------------------------------*/
uint32_t SystemCoreClock = __SYSTEM_CLOCK;/*!< System Clock Frequency (Core Clock)*/
/*----------------------------------------------------------------------------
Clock functions
*----------------------------------------------------------------------------*/
/**
* Update SystemCoreClock variable
*
* @param none
* @return none
*
* @brief Updates the SystemCoreClock with current core Clock
* retrieved from cpu registers.
*/
void SystemCoreClockUpdate (void)
{
SystemCoreClock = __SYSTEM_CLOCK;
}
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system.
* Initialize the System.
*/
void SystemInit (void)
{
#ifdef UNALIGNED_SUPPORT_DISABLE
SCB->CCR |= SCB_CCR_UNALIGN_TRP_Msk;
#endif
SystemCoreClock = __SYSTEM_CLOCK;
uart_init ( UART, (SystemCoreClock / 115200), 1,1,0,0,0,0 );
NVIC_EnableIRQ(SysTick_IRQn);
NVIC_EnableIRQ(ACC_IRQn);
NVIC_EnableIRQ(CAM_IRQn);
}

65
software/system_CM3DS.h Normal file
View File

@ -0,0 +1,65 @@
/**************************************************************************//**
* @file system_CM3DS_MPS2.h
* @brief CMSIS Cortex-M3 Device Peripheral Access Layer Header File for
* Device CM3DS_MPS2
* @version V3.01
* @date 06. March 2012
*
* @note
* Copyright (C) 2010-2012 ARM Limited. All rights reserved.
*
* @par
* ARM Limited (ARM) is supplying this software for use with Cortex-M
* processor based microcontrollers. This file can be freely distributed
* within development tools that are supporting such ARM based processors.
*
* @par
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
******************************************************************************/
#ifndef SYSTEM_CM3DS_MPS2_H
#define SYSTEM_CM3DS_MPS2_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
extern uint32_t SystemFrequency; /*!< System Clock Frequency (Core Clock) */
extern uint32_t SystemCoreClock; /*!< Processor Clock Frequency */
/**
* Initialize the system
*
* @param none
* @return none
*
* @brief Setup the microcontroller system.
* Initialize the System and update the SystemCoreClock variable.
*/
extern void SystemInit (void);
/**
* Update SystemCoreClock variable
*
* @param none
* @return none
*
* @brief Updates the SystemCoreClock with current core Clock
* retrieved from cpu registers.
*/
extern void SystemCoreClockUpdate (void);
#ifdef __cplusplus
}
#endif
#endif /* SYSTEM_CM3DS_MPS2_H */