* 07/16/96 This presentation will probably involve audience discussion, which will create action items. Use PowerPoint to keep track of these action items.

Slides:



Advertisements
Similar presentations
This presentation will probably involve audience discussion, which will create action items. Use PowerPoint to keep track of these action items during.
Advertisements

6/2/20151 This presentation will probably involve audience discussion, which will create action items. Use PowerPoint to keep track of these action items.
Systematic development of programs with parallel instructions SHARC ADSP2106X processor M. Smith, Electrical and Computer Engineering, University of Calgary,
Process for changing “C-based” design to SHARC assembler ADDITIONAL EXAMPLE M. R. Smith, Electrical and Computer Engineering University of Calgary, Canada.
This presentation will probably involve audience discussion, which will create action items. Use PowerPoint to keep track of these action items during.
Software and Hardware Circular Buffer Operations First presented in ENCM There are 3 earlier lectures that are useful for midterm review. M. R.
Improved Headphone Sound Stage Background to ENCM515 Labs on DSO Audio Channel Modeling Based on concepts in Bessinger Thesis Various copyrights M. Smith,
This presentation will probably involve audience discussion, which will create action items. Use PowerPoint to keep track of these action items during.
Generation of highly parallel code for TigerSHARC processors An introduction This presentation will probably involve audience discussion, which will create.
Getting the O in I/O to work on a typical microcontroller Activating a FLASH memory “output line” Part 1 Main part of Laboratory 1 Also needed for “voice.
Ultra sound solution Impact of C++ DSP optimization techniques.
Moving Arrays -- 1 Completion of ideas needed for a general and complete program Final concepts needed for Final Review for Final – Loop efficiency.
Digitalized Surround Sound Effects Using ADSP BF 533 Kunal Gupta ECE 3551, 03 Fall, 2006.
Efficient Loop Handling for DSP algorithms on CISC, RISC and DSP processors M. Smith, Electrical and Computer Engineering, University of Calgary, Alberta,
Systematic development of programs with parallel instructions SHARC ADSP21XXX processor M. Smith, Electrical and Computer Engineering, University of Calgary,
Moving Arrays -- 1 Completion of ideas needed for a general and complete program Final concepts needed for Final Review for Final – Loop efficiency.
واشوقاه إلى رمضان مرحباً رمضان
This presentation will probably involve audience discussion, which will create action items. Use PowerPoint to keep track of these action items during.
Software and Hardware Circular Buffer Operations
Generating the “Rectify” code (C++ and assembly code)
Post-Lab 1 Quiz Digital Thermometer Digital Storage Oscilloscope
Microcoded CCU (Central Control Unit)
This presentation will probably involve audience discussion, which will create action items. Use PowerPoint to keep track of these action items during.
Program Flow on ADSP2106X SHARC Pipeline issues
Overview of SHARC processor ADSP and ADSP-21065L
Overview of SHARC processor ADSP Program Flow and other stuff
Trying to avoid pipeline delays
ENCM K Interrupts Theory and Practice
Comparing 68k (CISC) with 21k (Superscalar RISC DSP)
Handling Arrays Completion of ideas needed for a general and complete program Final concepts needed for Final.
ENCM515 Standard and Custom FIR filters for Lab. 4
This presentation will probably involve audience discussion, which will create action items. Use PowerPoint to keep track of these action items during.
* M. R. Smith, University of Calgary, Alberta,
TigerSHARC processor and evaluation board
ENCM Course Hand-out Outline and Marking Scheme
Comparing 68k (CISC) with 21k (Superscalar RISC DSP)
Moving Arrays -- 1 Completion of ideas needed for a general and complete program Final concepts needed for Final Review for Final – Loop efficiency.
* 07/16/96 This presentation will probably involve audience discussion, which will create action items. Use PowerPoint to keep track of these action items.
* 07/16/96 This presentation will probably involve audience discussion, which will create action items. Use PowerPoint to keep track of these action items.
ENCM Course Hand-out Outline and Marking Scheme
Moving Arrays -- 2 Completion of ideas needed for a general and complete program Final concepts needed for Final DMA.
Overview of TigerSHARC processor ADSP-TS101 Compute Operations
Lab. 2 Modeling an audio channel with delays on ADSP21061
-- Tutorial A tool to assist in developing parallel ADSP2106X code
Single Value Processing Multi-Threaded Process
* From AMD 1996 Publication #18522 Revision E
Moving Arrays -- 2 Completion of ideas needed for a general and complete program Final concepts needed for Final DMA.
Handling Arrays Completion of ideas needed for a general and complete program Final concepts needed for Final.
* M. R. Smith 07/16/96 This presentation will probably involve audience discussion, which will create action items. Use PowerPoint.
This presentation will probably involve audience discussion, which will create action items. Use PowerPoint to keep track of these action items during.
* 2000/08/1307/16/96 This presentation will probably involve audience discussion, which will create action items. Use PowerPoint to keep track of these.
Getting serious about “going fast” on the TigerSHARC
Explaining issues with DCremoval( )
General Optimization Issues
Lab. 4 – Part 2 Demonstrating and understanding multi-processor boot
Handling Arrays Completion of ideas needed for a general and complete program Final concepts needed for Final.
Tutorial on Post Lab. 1 Quiz Practice for parallel operations
Overview of SHARC processor ADSP-2106X Compute Operations
Lab. 1 Modeling an audio channel with delays on ADSP21061
Overview of SHARC processor ADSP-2106X Compute Operations
* 07/16/96 This presentation will probably involve audience discussion, which will create action items. Use PowerPoint to keep track of these action items.
Overview of SHARC processor ADSP-2106X Memory Operations
Understanding the TigerSHARC ALU pipeline
This presentation will probably involve audience discussion, which will create action items. Use PowerPoint to keep track of these action items during.
A first attempt at learning about optimizing the TigerSHARC code
Working with the Compute Block
This presentation will probably involve audience discussion, which will create action items. Use PowerPoint to keep track of these action items during.
* 07/16/96 This presentation will probably involve audience discussion, which will create action items. Use PowerPoint to keep track of these action items.
* M. R. Smith 07/16/96 This presentation will probably involve audience discussion, which will create action items. Use PowerPoint.
ENCM515 Standard and Custom FIR filters
Presentation transcript:

* 07/16/96 This presentation will probably involve audience discussion, which will create action items. Use PowerPoint to keep track of these action items during your presentation In Slide Show, click on the right mouse button Select “Meeting Minder” Select the “Action Items” tab Type in action items as they come up Click OK to dismiss this box This will automatically create an Action Item slide at the end of your presentation with your points entered. Stereo Sound repositioning Details of hardware FIFO buffers Hardware FIFO in “C” M. R. Smith, Electrical and Computer Engineering University of Calgary, Alberta, Canada smithmr @ ucalgary.ca *

To be tackled today Concept of Lab. 2 -- Software FIFO stack * 07/16/96 Concept of Lab. 2 -- Software FIFO stack Software Circular Buffers -- 2 approaches FIFO stacks allowing the modeling of audio channels associated with sound positioning through delays Details of Lab. 3 -- Hardware FIFO stack Same code except for variants of new routine Compare software and hardware circular buffers Developing new code in Assembly code Delay line as FIR, FIR coeffs in dm or pm space Hardware circular buffer in assembly code 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca *

Labs. 2 and 3 -- delay line -- Concept * 07/16/96 DELAY1 No delay between left/right ear sound arrivals -- then sound perceived in centre of head Delay in right ear sound arrival will shift sound to left as “sound” seems to get to left ear first O DELAY DELAY2 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca *

DAG generator architecture * 07/16/96 Animation from SHARCNavigator from Web Also see DSP workshop book and exercises 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca *

Audio channel delay modeled using software circular buffers * Audio channel delay modeled using software circular buffers 07/16/96 void SoftCircularBuffer_LeftDelay(int delay, int *channel_one) { int count; static float left_delayline[MAXDELAY] = {0}; static float *left_pt_out = &left_delayline[0]; (Points to most delayed sample) static float *overflow_pt = &left_delayline[MAXDELAY]; float *left_pt_in = left_pt_out + delay; // CAREFULL point offset size if (left_pt_in >= overflow_pt) left_pt_in - MAXDELAY; // Insert new value into the back of the FIFO delay line *left_pt_in = (float) *channel_one; // Grab delayed value from the front of the FIFO delay line *channel_one = (int) *left_pt_out; // Update the FIFO delay line using pointer arithmetic for circ. Buff left_pt_out++; if (left_pt_out >= overflow_pt) left_pt_out = left_pt_out - MAXDELAY; } // SPEED OF CODE -- INDEPENDENT OF DELAY SIZE 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca *

Principle of Hardware Circular Buffers * 07/16/96 AFTER APPLYING MAGIC void SoftCircularBuffer_LeftDelay(int delay, int *channel_one) { int count; static float left_delayline[MAXDELAY] = {0}; static float *left_pt_out = &left_delayline[0]; (Points to most delayed sample) static float *overflow_pt = &left_delayline[MAXDELAY]; float *left_pt_in = left_pt_out + delay; // CAREFULL point offset size if (left_pt_in >= overflow_pt) left_pt_in - MAXDELAY; // Insert new value into the back of the FIFO delay line *left_pt_in = (float) *channel_one; // Grab delayed value from the front of the FIFO delay line *channel_one = (int) *left_pt_out; // Update the FIFO delay line using pointer arithmetic for circ. Buff left_pt_out++; MAGIC OCCURS AND POINTER POSITION OKAY if (left_pt_out >= overflow_pt) left_pt_out = left_pt_out - MAXDELAY; } // SPEED OF CODE -- INDEPENDENT OF DELAY SIZE 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca *

Approach Set up B4, I4, L4 and M4 for circular buffers and use them Problems Working in a multi-tasking environment Working with “C/C++” interrupt environment Working with normal “C” Everybody using the same set of registers ADVANTAGE THIS LECTURE We know more than the compiler does 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca

MySetUp( ) ADIsound soundemo; MySetUp( ); -- Sets up circular buffer while (ReadSource(&left_in) ) { -- Use circular buffer ProcessSound(left_in, &left_out) ; WriteSource(left_out); } 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca

MySetUp( ) – Non-21XXX processor float * start_of_FIFOarray = GARBAGE; int length_of_FIFOarray = GARBAGE; float *current_FIFO_oldest_pointer = GARBAGE; float left_channel[MAXLENGTH]; MySetUp( ) { SaveMyEars(left_channel, MAXLENGTH) – Make 0 length_of_FIFOarray = MAXLENGTH start_of_FIFOarray = left_channel; current_FIFO_oldest_pointer = left_channel; “C” convention – means &left_channel[0]; 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca

Modeling Audio Channel Delays using Mass Memory Moves * 07/16/96 Modeling Audio Channel Delays using Mass Memory Moves #define MAXDELAY 0x80 void MemoryMove_LeftDelay(int delay, int *channel_one) { int count; static float left_delayline[MAXDELAY] = {0}; // Insert new value into the back of the FIFO delay line left_delayline[0 + delay] = (float) *channel_one; // Grab delayed value from the front of the FIFO delay line *channel_one = (int) left_delayline[0]; // Update the FIFO delay line using inefficient memory moves for (count = 0; count < delay; count++) left_delayline[count] = left_delayline[count + 1]; } 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca *

Principle of Hardware Circular Buffers * 07/16/96 float * start_of_FIFOarray; int length_of_FIFOarray; float *current_FIFO_oldest_pointer; AFTER APPLYING MAGIC -- MySetUp() #pragma – Please use circular buffers – there is an actual “C” extension I forget the exact syntax -- SHARC and Blackfin similar void SoftCircularBuffer_LeftDelay(int delay, int *channel_one) { int count; int temp; temp = *current_FIFP_oldest_pointer; // Get oldest value *current_FIFO_oldest_pointer = *channel_one; // Replace with newest value *channel_one = temp; current_FIFO_oldest_pointer++; // Letting hardware buffer work // Equivalent would happen in FIR – except working in a loop } // SPEED OF CODE -- INDEPENDENT OF DELAY SIZE 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca *

What “Compiler” actually has to do * 07/16/96 void SoftCircularBuffer_LeftDelay(int delay, int *channel_one) { int count; int temp; Save the following registers to the stack I3, L3, B3 (and perhaps M3) THEN DO B3 = start_of_FIFO_array; L3 = length_of_FIFO_array I3 = current_FIFO_oldest_pointer; Now use I3, B3 and L3 for hardware operations temp = *current_FIFP_oldest_pointer; // Get oldest value *current_FIFO_oldest_pointer = *channel_one; // Replace with newest value *channel_one = temp; current_FIFO_oldest_pointer++; current_FIFO_oldest_pointer = I3 -- remember the pointer Recover the following registers from the stack I3, L3, B3 (and perhaps M3) // Equivalent would happen in FIR – except working in a loop } // so save / recovery of registers is not as big an over-head 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca *

New Knowledge 68K, Blackfin Live with the overhead (previous slides) AMD 29K – 128 registers – set some aside specially for special purposes – untouchable by compiler Alternate sets of registers Intel i960 – 15 sets of alternate general registers SHARC – 2 sets of data and DAG registers that are selectable in banks 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca

MySetUp( ) –21XXX processor float * start_of_FIFOarray = GARBAGE; // Use alternate int length_of_FIFOarray = GARBAGE; float *current_FIFO_oldest_pointer = GARBAGE; float left_channel[MAXLENGTH]; MySetUp( ) { SaveMyEars(left_channel, MAXLENGTH) – Make 0 DeactivateInterrupts( ); SwitchToMyAlternateRegisters( ); length_of_FIFOarray = MAXLENGTH -- Alternate L2 start_of_FIFOarray = left_channel; -- Alternate B2 current_FIFO_oldest_pointer = left_channel; -- Alternate I2 Could do L3, B3 and I3 for right channel, but other techniques possible SwitchToOriginalRegisters( ) ReactivateInterrupts( ); 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca

Hardware Circular Buffers – Pseudo Code * 07/16/96 AFTER APPLYING MAGIC -- MySetUp() All necessary information in “Alternate Registers void HardCircularBuffer_LeftDelay_ASM(int delay, int *channel_one) { int temp; DeactivateInterrupts( ); SwitchToMyAlternateRegisters( ); temp = *current_FIFP_oldest_pointer; // Get oldest value *current_FIFO_oldest_pointer = *channel_one; // Replace with newest value *channel_one = temp; current_FIFO_oldest_pointer++; // Letting hardware buffer work SwitchToOriginalRegisters( ) ReactivateInterrupts( ); // Equivalent would happen in FIR – except working in a loop } // SPEED OF CODE -- INDEPENDENT OF DELAY SIZE 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca *

Issues -- 1 Can’t just switch to alternate register bank and back to original Multi-tasking environment – may already be in alternate bank – e.g. interrupted an assembly program already using the alternate register bank Solution – save and recover PROCESSOR CONFIGURATION 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca

Issues -- 2 Can’t just switch to alternate register bank and back to original We need R0 (return), R4 (INPAR1) etc unchanged Another interrupt may come along and want to use stack to store values during ISR Solution – be selective on what registers you use Solution – Deactivate interrupts – and know the amount of time that system can’t respond. 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca

MODE1 register Memory mapped system register – typical today #include "def21061.h" #include "clanguage_21XXXregister_defines.i“ bit set MODE1 BitPattern; nop bit clr MODE1 BitPattern; nop PROBLEM – Can’t use the alternate registers for 1 cycle – possible race condition SOLUTION – NOP after changing – guarentees no problem 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca

MySetUp( ) –21XXX processor float * start_of_FIFOarray = GARBAGE; // Use alternate int length_of_FIFOarray = GARBAGE; float *current_FIFO_oldest_pointer = GARBAGE; float left_channel[MAXLENGTH]; MySetUp( ) { SaveMyEars(left_channel, MAXLENGTH) – Make 0 SetUpAlternateRegisters_ASM( ); } 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca

MySetUp( ) –21XXX processor .extern _left_channel[MAXLENGTH]; ALL NECESSARY DEFINES _SetUpAlternateRegisters_ASM( ) { DeactivateInterrupts( ); -- Might already be de-activated SwitchToMyAlternateRegisters( ); -- Might already be in alternate bank // length_of_FIFOarray = MAXLENGTH LEFT_LENGTH_Alt_L2 = MAXLENGTH; // start_of_FIFOarray = _left_channel; LEFT_BASE_Alt_B2 = _left_channel; // Has side effect // current_FIFO_oldest_pointer = left_channel; LEFT_OLD_pt_Alt_I2 = _left_channel; // Overcomes side effect SwitchToMyOriginalRegisters( ); -- Might not want to switch back ReactivateInterrupts( ); -- Might not want to be activated 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca

MODE1 register Details – Appendix on E-14 of MANUAL Bit 2 – SRCU – alternate register select for computation units? Bit 3 – SRD1H – DAG1 alternate register select (7-4) – DON’T TOUCH – “C” issue Bit 4 – SRD1L – DAG1 alternate register select (3-0) Bit 5 – SRD2H – DAG2 alternate register select (15-12) Bit 6 – SRD2L – DAG2 alternate register select (11-8) Bit 7 – SRRFH – Register file alternate select for R15-R8 Bit 10 – SRRFL – Register file alternate select for R7-R0 Bit 12 – IRPTEN – Global interrupt enable 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca

Useful Macros -- Define Going to be doing this stuff often Define assembly language macros #define TOAlternateRegisters() bit set MODE1 SRRFL; nop #define FROMAlternateRegisters() bit clr MODE1 SRRFL; nop 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca

MySetUp( ) –21XXX processor #define DeactivateInterrupts( ) ????????? #define SwitchToMyAlternateRegisters( ) ????????? _SetUpAlternateRegisters_ASM( ) { R0 = MODE1; // In this case, we know R0 is not being destroyed DeactivateInterrupts( ); -- // Might already be deactivate SwitchToMyAlternateRegisters( ); // length_of_FIFOarray = MAXLENGTH LEFT_LENGTH_Alt_L2 = MAXLENGTH; // start_of_FIFOarray = _left_channel; LEFT_BASE_Alt_B2 = _left_channel; // Has side effect // current_FIFO_oldest_pointer = left_channel; LEFT_OLD_pt_Alt_I2 = _left_channel; // Overcomes side effect PROBLEM – HOW TO GET BACK TO ORIGINAL R0 WITHOUT UNINTENTIONALLY CAUSING A PROBLEM? SwitchToMyOriginalRegisters( ); -- Might not want to switch back ReactivateInterrupts( ); -- Might not want to be activated 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca

Solution 1 – valid here _SetUpAlternateRegisters_ASM( ) { #define DeactivateInterrupts( ) ????????? #define SwitchToMyAlternateDAGRegisters( ) ????????? _SetUpAlternateRegisters_ASM( ) { R0 = MODE1; // In this case, we know R0 is not being destroyed DeactivateInterrupts( ); -- // Might already be deactivate SwitchToMyAlternateDAG1LRegisters( ); // length_of_FIFOarray = MAXLENGTH LEFT_LENGTH_Alt_L2 = MAXLENGTH; // start_of_FIFOarray = _left_channel; LEFT_BASE_Alt_B2 = _left_channel; // Has side effect // current_FIFO_oldest_pointer = left_channel; LEFT_OLD_pt_Alt_I2 = _left_channel; // Overcomes side effect NO PROBLEM – HOW TO GET BACK TO ORIGINAL R0 WITHOUT UNINTENTIONALLY CAUSING A PROBLEM? MODE1 = R0; // SwitchToMyOriginalRegisters( ); -- Might not want to switch back // ReactivateInterrupts( ); -- Might not want to be activated 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca

Solution 2 – valid elsewhere #define DeactivateInterrupts( ) ????????? #define SwitchToMyAlternateRegisters( ) ????????? _SetUpAlternateRegisters_ASM( ) { R0 = MODE1; // In this case, we know R0 is not being destroyed SAVE R0 TO THE STACK USING I6, I7 – which we know are not to be used DeactivateInterrupts( ); -- // Might already be deactivate SwitchToMyAlternateRegisters( ); // length_of_FIFOarray = MAXLENGTH LEFT_LENGTH_Alt_L2 = MAXLENGTH; // start_of_FIFOarray = _left_channel; LEFT_BASE_Alt_B2 = _left_channel; // Has side effect // current_FIFO_oldest_pointer = left_channel; LEFT_OLD_pt_Alt_I2 = _left_channel; // Overcomes side effect NO PROBLEM – HOW TO GET BACK TO ORIGINAL R0 WITHOUT UNINTENTIONALLY CAUSING A PROBLEM? RECOVER R0 FROM THE STACK MODE1 = R0; // SwitchToMyOriginalRegisters( ); -- Might not want to switch back // ReactivateInterrupts( ); -- Might not want to be activated 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca

Lab. 3 Implement hardware circular buffers – replace the software circular buffers code from Lab. 2 Demonstrate moving sound source using LOCAL_AUDIOSOURCE WARNING – LOCAL_AUDIO_SOURCE is ALREADY using hardware circular buffers (I0 and I1) CODEC_AUDIOSOURCE Complete Lab. 2 / Lab. 3 joint report discussing timing issues / advantages / disadvantages of the various approaches. Provide documented code Demo the working versions of the code either during Lab.3 or Lab. 4 Joint report due at the start of the Friday lecture for your Lab. 4, which is a week extension over being due within a week of your lab. Late penalties will be applied. 1/17/2019 ENCM515 -- Hardware FIFO buffers -- Details of Lab. 3 Copyright M. Smith -- smithmr@ucalgary,ca