Add files via upload
This commit is contained in:
parent
bc35eec7cb
commit
00044b6750
BIN
Docs/Keil and Vivado Configurations.pdf
Normal file
BIN
Docs/Keil and Vivado Configurations.pdf
Normal file
Binary file not shown.
502
hardware/bus/ahb/cmsdk_L1AhbMtx/cmsdk_L1AhbMtx.v
Normal file
502
hardware/bus/ahb/cmsdk_L1AhbMtx/cmsdk_L1AhbMtx.v
Normal 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 ===================================--
|
138
hardware/bus/ahb/cmsdk_L1AhbMtx/cmsdk_L1AhbMtx_default_slave.v
Normal file
138
hardware/bus/ahb/cmsdk_L1AhbMtx/cmsdk_L1AhbMtx_default_slave.v
Normal 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 ===================================--
|
353
hardware/bus/ahb/cmsdk_L1AhbMtx/cmsdk_L1AhbMtx_lite.v
Normal file
353
hardware/bus/ahb/cmsdk_L1AhbMtx/cmsdk_L1AhbMtx_lite.v
Normal 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
|
159
hardware/bus/ahb/cmsdk_L1AhbMtx/cmsdk_MyArbiterName.v
Normal file
159
hardware/bus/ahb/cmsdk_L1AhbMtx/cmsdk_MyArbiterName.v
Normal 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 ===================================--
|
341
hardware/bus/ahb/cmsdk_L1AhbMtx/cmsdk_MyDecoderNameS0_SYS.v
Normal file
341
hardware/bus/ahb/cmsdk_L1AhbMtx/cmsdk_MyDecoderNameS0_SYS.v
Normal 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 ===================================--
|
471
hardware/bus/ahb/cmsdk_L1AhbMtx/cmsdk_MyInputName.v
Normal file
471
hardware/bus/ahb/cmsdk_L1AhbMtx/cmsdk_MyInputName.v
Normal 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 ===================================--
|
379
hardware/bus/ahb/cmsdk_L1AhbMtx/cmsdk_MyOutputName.v
Normal file
379
hardware/bus/ahb/cmsdk_L1AhbMtx/cmsdk_MyOutputName.v
Normal 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 ===================================--
|
436
hardware/bus/apb/cmsdk_ahb_to_apb.v
Normal file
436
hardware/bus/apb/cmsdk_ahb_to_apb.v
Normal 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
|
226
hardware/bus/apb/cmsdk_apb_slave_mux.v
Normal file
226
hardware/bus/apb/cmsdk_apb_slave_mux.v
Normal 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
91
hardware/constraint.xdc
Normal 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]
|
94613
hardware/core/cortexm3ds_logic.v
Normal file
94613
hardware/core/cortexm3ds_logic.v
Normal file
File diff suppressed because it is too large
Load Diff
71
hardware/ddr3.ucf
Normal file
71
hardware/ddr3.ucf
Normal 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
59906
hardware/facefinder.coe
Normal file
File diff suppressed because it is too large
Load Diff
1771
hardware/minSOC.v
Normal file
1771
hardware/minSOC.v
Normal file
File diff suppressed because it is too large
Load Diff
821
hardware/peripheral/accelerator/accelerator.v
Normal file
821
hardware/peripheral/accelerator/accelerator.v
Normal 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
|
48
hardware/peripheral/btn/custom_apb_button.v
Normal file
48
hardware/peripheral/btn/custom_apb_button.v
Normal 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
|
||||
|
||||
|
350
hardware/peripheral/camera/aq_axi_master_cam.v
Normal file
350
hardware/peripheral/camera/aq_axi_master_cam.v
Normal 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
|
||||
|
55
hardware/peripheral/camera/cmos_8_16bit.v
Normal file
55
hardware/peripheral/camera/cmos_8_16bit.v
Normal 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
|
56
hardware/peripheral/camera/cmos_write_req_gen.v
Normal file
56
hardware/peripheral/camera/cmos_write_req_gen.v
Normal 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
|
357
hardware/peripheral/camera/color_bar.v
Normal file
357
hardware/peripheral/camera/color_bar.v
Normal 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
|
66
hardware/peripheral/camera/dvi_encoder.v
Normal file
66
hardware/peripheral/camera/dvi_encoder.v
Normal 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
|
177
hardware/peripheral/camera/encode.v
Normal file
177
hardware/peripheral/camera/encode.v
Normal 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
|
227
hardware/peripheral/camera/frame_fifo_read_cam.v
Normal file
227
hardware/peripheral/camera/frame_fifo_read_cam.v
Normal 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
|
241
hardware/peripheral/camera/frame_fifo_write_cam.v
Normal file
241
hardware/peripheral/camera/frame_fifo_write_cam.v
Normal 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
|
153
hardware/peripheral/camera/frame_read_write_cam.v
Normal file
153
hardware/peripheral/camera/frame_read_write_cam.v
Normal 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
|
129
hardware/peripheral/camera/i2c_master/i2c_config.v
Normal file
129
hardware/peripheral/camera/i2c_master/i2c_config.v
Normal 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
|
620
hardware/peripheral/camera/i2c_master/i2c_master_bit_ctrl.v
Normal file
620
hardware/peripheral/camera/i2c_master/i2c_master_bit_ctrl.v
Normal 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
|
350
hardware/peripheral/camera/i2c_master/i2c_master_byte_ctrl.v
Normal file
350
hardware/peripheral/camera/i2c_master/i2c_master_byte_ctrl.v
Normal 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 operator,just 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
|
59
hardware/peripheral/camera/i2c_master/i2c_master_defines.v
Normal file
59
hardware/peripheral/camera/i2c_master/i2c_master_defines.v
Normal 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
|
256
hardware/peripheral/camera/i2c_master/i2c_master_top.v
Normal file
256
hardware/peripheral/camera/i2c_master/i2c_master_top.v
Normal 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
|
2
hardware/peripheral/camera/i2c_master/timescale.v
Normal file
2
hardware/peripheral/camera/i2c_master/timescale.v
Normal file
@ -0,0 +1,2 @@
|
||||
`timescale 1ns / 10ps
|
||||
|
346
hardware/peripheral/camera/lut_ov5640_rgb565_640_480.v
Normal file
346
hardware/peripheral/camera/lut_ov5640_rgb565_640_480.v
Normal 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
|
179
hardware/peripheral/camera/serdes_4b_10to1.v
Normal file
179
hardware/peripheral/camera/serdes_4b_10to1.v
Normal 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
|
1
hardware/peripheral/camera/video_define.v
Normal file
1
hardware/peripheral/camera/video_define.v
Normal file
@ -0,0 +1 @@
|
||||
`define VIDEO_640_480
|
113
hardware/peripheral/camera/video_timing_data.v
Normal file
113
hardware/peripheral/camera/video_timing_data.v
Normal 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
|
1129
hardware/peripheral/cmsdk_apb_uart.v
Normal file
1129
hardware/peripheral/cmsdk_apb_uart.v
Normal file
File diff suppressed because it is too large
Load Diff
98
hardware/peripheral/igniter/igniter.v
Normal file
98
hardware/peripheral/igniter/igniter.v
Normal 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
|
||||
|
||||
|
115
hardware/peripheral/led/cmsdk_apb3_eg_slave_interface_led.v
Normal file
115
hardware/peripheral/led/cmsdk_apb3_eg_slave_interface_led.v
Normal 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
|
||||
|
||||
|
149
hardware/peripheral/led/cmsdk_apb3_eg_slave_led.v
Normal file
149
hardware/peripheral/led/cmsdk_apb3_eg_slave_led.v
Normal 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
|
29
hardware/peripheral/led/custom_apb_led.v
Normal file
29
hardware/peripheral/led/custom_apb_led.v
Normal 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
|
65
hardware/peripheral/sram/AHB2ROM.v
Normal file
65
hardware/peripheral/sram/AHB2ROM.v
Normal 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
|
94
hardware/peripheral/timer/custom_apb_timer.v
Normal file
94
hardware/peripheral/timer/custom_apb_timer.v
Normal 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
284
software/CM3DS_MPS2.h
Normal 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 */
|
||||
|
356
software/CM3DS_MPS2_driver.c
Normal file
356
software/CM3DS_MPS2_driver.c
Normal 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;
|
||||
}
|
145
software/CM3DS_MPS2_driver.h
Normal file
145
software/CM3DS_MPS2_driver.h
Normal 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
13
software/RGBprocess.h
Normal 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
55
software/Retarget.c
Normal 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
1627
software/core_cm3.h
Normal file
File diff suppressed because it is too large
Load Diff
636
software/core_cmFunc.h
Normal file
636
software/core_cmFunc.h
Normal 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
688
software/core_cmInstr.h
Normal 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
59
software/handler.c
Normal 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
184
software/main.c
Normal 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
463
software/picornt.c
Normal 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棵树,每棵树进行6层二分类,最终获得一个confidence,
|
||||
* 每棵树的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;
|
||||
//
|
||||
// // 一棵树沿深度方向的二元决策,决策判据是这棵树各层所指定图像位置的强度
|
||||
// // 经过tdepth(6层)决策后,得到最终所落在的位置是 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
31
software/picornt.h
Normal 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
250
software/startup_CM3DS.s
Normal 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
97
software/system_CM3DS.c
Normal 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
65
software/system_CM3DS.h
Normal 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 */
|
Loading…
x
Reference in New Issue
Block a user