FPGA 实现CAN通信

devtools/2024/11/9 0:17:15/

使用FPGA+SJA 1000芯片实现CAN通信。核心思路是对集成CAN协议的芯片尽心配置,来进行CAN通信。核心顶层代码:

//-- Company:     
//-- Engineer: 
//-- 
//-- Create Date:    11:18:25 12/01/2021
//-- Design Name: 
//-- Module Name:    con_port - Behavioral 
//-- Project Name: 
//-- Target Devices: 
//-- Tool versions: 
//-- Description: peliCAN 
//-- Dependencies: 
//-- -- Revision					date			  author				description 
//--		v1.0 					 12/01/2021			HLC			    File Created
// ???sja1000???????? FPGA up?????sja1000 up?????????????????//2020?12?26?14:43:01
//???????????????????????????????
//??????????????//2021?1?14?11:17:04 ??????????????module can_port (input          clk_in         ,//clk==40minput          reset          ,input          re_config      ,//????? ????????????????sja1000input          can_auto_reset ,//CAN????? 5s?????????????sja1000/*input [7:0]     CAN_ID0_tx     ,//ID1-4???????ID?input [7:0]     CAN_ID1_tx     ,//ID0????(frame information)input [7:0]     CAN_ID2_tx     ,input [7:0]	    CAN_ID3_tx	  ,//EFFinput [7:0]	    CAN_ID4_tx	  ,//EFFinput [7:0]     CAN_DATA1_tx   ,//?????8????input [7:0]     CAN_DATA2_tx   ,input [7:0]     CAN_DATA3_tx   ,input [7:0]     CAN_DATA4_tx   ,input [7:0]     CAN_DATA5_tx   ,input [7:0]     CAN_DATA6_tx   ,input [7:0]     CAN_DATA7_tx   ,input [7:0]     CAN_DATA8_tx   ,*/output reg[7:0]CAN_ID0_rx     ,//ID1-4???????ID?output reg[7:0]CAN_ID1_rx     ,//ID0????(frame information)output reg[7:0]CAN_ID2_rx     ,output reg[7:0]CAN_ID3_rx	  ,//EFFoutput reg[7:0]CAN_ID4_rx	  ,//EFFoutput reg[7:0]CAN_DATA1_rx   ,//????8????output reg[7:0]CAN_DATA2_rx   ,output reg[7:0]CAN_DATA3_rx   ,output reg[7:0]CAN_DATA4_rx   ,output reg[7:0]CAN_DATA5_rx   ,output reg[7:0]CAN_DATA6_rx   ,output reg[7:0]CAN_DATA7_rx   ,output reg[7:0]CAN_DATA8_rx   ,	 //ATTENTION! The real CAN_ID received, is equal to//{3'b000, CAN_ID1_rx, CAN_ID2_rx, CAN_ID3_rx, CAN_ID4_rx[7:3]};//which seems like right shift 3 bits.input       CAN_DATA_SEND_EN  ,//?????? ???????????output reg CAN_DATA_SEND_DONE ,//???????? ?????????????output reg CAN_DATA_RECV_DONE ,//???????? ?????????CAN_DATA_rx???output reg DATA_RECEIVE_DO    ,//????????????????output       CAN_ALE          ,//??sja1000?????      output       CAN_WR           ,//??sja1000?????      output       CAN_RD           ,//??sja1000?????      output       CAN_CS           ,//??sja1000?????      output reg   CAN_RST          ,//??sja1000?????//   CAN_clk_in                    ,//??sja1000?????inout [7:0]  DATA_CAN         ,//??sja1000???ad??output       en                //??????  DATA_CAN????SJA1000??????? en????????? 		 
);//for watching
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_ID0_rx;  
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_ID1_rx;   
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_ID2_rx;   
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_ID3_rx;	
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_ID4_rx;	
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_DATA1_rx; 
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_DATA2_rx; 
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_DATA3_rx; 
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_DATA4_rx; 
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_DATA5_rx; 
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_DATA6_rx; 
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_DATA7_rx; 
(*KEEP = "TRUE"*) reg[7:0]tmp_CAN_DATA8_rx; always @ (posedge clk_in or posedge reset) beginif (reset) begintmp_CAN_ID0_rx <= 8'h00;tmp_CAN_ID1_rx <= 8'h00;tmp_CAN_ID2_rx <= 8'h00;tmp_CAN_ID3_rx <= 8'h00;tmp_CAN_ID4_rx <= 8'h00;tmp_CAN_DATA1_rx <= 8'h00;tmp_CAN_DATA2_rx <= 8'h00;tmp_CAN_DATA3_rx <= 8'h00;tmp_CAN_DATA4_rx <= 8'h00;tmp_CAN_DATA5_rx <= 8'h00;tmp_CAN_DATA6_rx <= 8'h00;tmp_CAN_DATA7_rx <= 8'h00;tmp_CAN_DATA8_rx <= 8'h00;endelse if (DATA_RECEIVE_DO) begintmp_CAN_ID0_rx <= CAN_ID0_rx;   tmp_CAN_ID1_rx <= CAN_ID1_rx;   tmp_CAN_ID2_rx <= CAN_ID2_rx;   tmp_CAN_ID3_rx <= CAN_ID3_rx;	tmp_CAN_ID4_rx <= CAN_ID4_rx;	tmp_CAN_DATA1_rx <= CAN_DATA1_rx; tmp_CAN_DATA2_rx <= CAN_DATA2_rx; tmp_CAN_DATA3_rx <= CAN_DATA3_rx; tmp_CAN_DATA4_rx <= CAN_DATA4_rx; tmp_CAN_DATA5_rx <= CAN_DATA5_rx; tmp_CAN_DATA6_rx <= CAN_DATA6_rx; tmp_CAN_DATA7_rx <= CAN_DATA7_rx; tmp_CAN_DATA8_rx <= CAN_DATA8_rx; endelse begintmp_CAN_ID0_rx   <= tmp_CAN_ID0_rx   ; tmp_CAN_ID1_rx   <= tmp_CAN_ID1_rx   ;tmp_CAN_ID2_rx   <= tmp_CAN_ID2_rx   ;tmp_CAN_ID3_rx   <= tmp_CAN_ID3_rx   ;tmp_CAN_ID4_rx   <= tmp_CAN_ID4_rx   ;tmp_CAN_DATA1_rx <= tmp_CAN_DATA1_rx ;tmp_CAN_DATA2_rx <= tmp_CAN_DATA2_rx ;tmp_CAN_DATA3_rx <= tmp_CAN_DATA3_rx ;tmp_CAN_DATA4_rx <= tmp_CAN_DATA4_rx ;tmp_CAN_DATA5_rx <= tmp_CAN_DATA5_rx ;tmp_CAN_DATA6_rx <= tmp_CAN_DATA6_rx ;tmp_CAN_DATA7_rx <= tmp_CAN_DATA7_rx ;tmp_CAN_DATA8_rx <= tmp_CAN_DATA8_rx ;end
end//===================================================================================
//??ID???????? at 2021?1?13?14:35:51
//SJA1000T????29??ID28-ID0????ID????ID??3bit?
//?CAN???????ID?????????????3bit??????? ID_test ??
//CAN?????ID??SJA1000T????ID???3bit?????ID????3bit??
//real_recv_id = {3'b000, CAN_ID1_rx, CAN_ID2_rx, CAN_ID3_rx, CAN_ID4_rx[7:3]};
//====================================================================================reg [31:0] real_recv_id;
//wire real_recv_id = CAN_DATA_RECV_DONE ? {3'b000, CAN_ID1_rx, CAN_ID2_rx, CAN_ID3_rx, CAN_ID4_rx[7:3]} : 32'b0;
always @ (posedge clk_in or posedge reset) beginif (reset)real_recv_id <= 32'b0;else if (CAN_DATA_RECV_DONE)real_recv_id <= {3'b000, CAN_ID1_rx, CAN_ID2_rx, CAN_ID3_rx, CAN_ID4_rx[7:3]};elsereal_recv_id <= real_recv_id;
end//?????????????IO banks??????????input???????//???????????????//?????????parameter ID_test = 32'h0C080C00;  //ID_test[31:0];parameter CAN_ID0_tx   = 8'b1000_1000;//{FF, RTR, 0, 0, DLC3, DLC2, DLC1, DLC0};parameter CAN_ID1_tx   = ID_test[28:21];parameter CAN_ID2_tx   = ID_test[20:13];parameter CAN_ID3_tx   = ID_test[12:05];parameter CAN_ID4_tx   = {ID_test[4:0], 3'b000};//this seems like left shift 3 bits.parameter CAN_DATA1_tx = 8'h90;	//??DYT??????3547200ms, ?'h8A90parameter CAN_DATA2_tx = 8'h8A;	//????????????????parameter CAN_DATA3_tx = 8'h06;	//??'h90_8A_00_00_00_00_00_00parameter CAN_DATA4_tx = 8'h05; //????????CAN_DATA?????00???parameter CAN_DATA5_tx = 8'h04;parameter CAN_DATA6_tx = 8'h03;parameter CAN_DATA7_tx = 8'h02;parameter CAN_DATA8_tx = 8'h01;parameter          INIT_RESET =5'b00001,INIT       =5'b00010,IDLE       =5'b00100,DATA_READ  =5'b01000,DATA_SEND  =5'b10000;		
reg [4:0]    state_c,state_n;	//********************************************
reg          read_act_path;
reg          read_write0  ;
reg [7:0]    read_addr_path;
reg [7:0]    read_data_path;
reg [3:0]    read_state   ; 
reg [3:0]    read_cnt     ;
reg          read_finish  ;//********************************************
//**************************************************************************************
reg        act            ;
reg        write0         ;
wire       recv_done_path ;
wire       send_done_path ;
reg [7:0]  need_addr_path ;
wire[7:0]  recv_data_path ;
reg [7:0]  s_data_path ;	
//new adding at 2021?1?14?11:18:01
(*KEEP = "TRUE"*) reg [3:0] tx_DLC; //tx data length counter
(*KEEP = "TRUE"*) reg [3:0] rx_DLC; //rx data length counter
always @ (posedge clk_in or posedge reset) beginif (reset)tx_DLC <= 4'h0;else if (state_n == DATA_SEND) begintx_DLC <= ((CAN_ID0_tx[3] << 3) + (CAN_ID0_tx[2] << 2) + (CAN_ID0_tx[1] << 1) + CAN_ID0_tx[0]);endelsetx_DLC <= 4'h0;
endalways @ (posedge clk_in or posedge reset) beginif (reset)rx_DLC <= 4'h0;else if ((state_n == DATA_READ)) beginif ((read_cnt == 4'd1) && recv_done_path)rx_DLC <= ((CAN_ID0_rx[3] << 3) + (CAN_ID0_rx[2] << 2) + (CAN_ID0_rx[1] << 1) + CAN_ID0_rx[0]);elserx_DLC <= rx_DLC;endelserx_DLC <= 4'h0;
end//========================================================
//for watching
//========================================================
(*KEEP = "TRUE"*) reg[7:0]CAN_ID_rx_r[4:0]     ;
(*KEEP = "TRUE"*) reg[7:0]CAN_DATA_r[7:0];reg [7:0]  init_addr[13:0];
reg [7:0]  init_data[13:0];
reg [7:0]  rx_tx_addr[12:0]; //SFF
reg [7:0]  tx_data[10:0] ;//SFF//reg [7:0] rx_tx_addr[14:0];//EFF
//reg [7:0] tx_data[12:0];//EFF(*KEEP = "TRUE"*) reg [7:0]  CAN_RXERR_rx,CAN_TXERR_rx;
reg        send_flag     ;
//******************************************
reg [15:0]    cnt         ;
reg          init_restf  ;//initialize reset finish ???????
//****************************************
wire         need_reset;
reg [31:0]   reset_cnt;
//***************************************************
reg [3:0]    init_cnt;
reg          init_act_path;
reg          init_write0  ;
reg          init_finish  ;
reg [7:0]    init_addr_path;
reg [7:0]    init_data_path;
reg [2:0]    init_state   ;
//******************************************
reg          idle_act_path;
reg          idle_write0  ;
reg [7:0]    idle_addr_path;
(*KEEP = "TRUE"*) reg [7:0]    idle_sr_data;
(*KEEP = "TRUE"*) reg [2:0]    idle_state   ; 
reg          need_read    ;
reg          need_send    ;	//***************************************************
reg          send_act_path ;
reg          send_write0   ;
(*KEEP = "TRUE"*) reg [7:0]    send_addr_path;
(*KEEP = "TRUE"*) reg [7:0]    send_data_path;
reg [3:0]    send_state   ;
reg [3:0]    send_cnt     ; 
reg          send_finish  ;reg idle_sr_data3;
reg idle_sr_data5;
(*KEEP = "TRUE"*) wire sr3_AND_sr5;
assign sr3_AND_sr5 = idle_sr_data3 && idle_sr_data5;
always @ (posedge clk_in) beginif (reset)idle_sr_data5 <= 1'b0;elseidle_sr_data5 <= idle_sr_data[5];
end always @ (posedge clk_in) beginif (reset)idle_sr_data3 <= 1'b0;elseidle_sr_data3 <= idle_sr_data[3];
end 
//********************** ???????? ??????????sja1000***************************************************************
always @(posedge clk_in) begin //?14?addrif (reset)  begin init_addr[0 ]<=8'h00 ;  //MOD     ????SJA1000??????init_addr[1 ]<=8'h00 ;  //TIMER0init_addr[2 ]<=8'h00 ;  //TIMER1init_addr[3 ]<=8'h00 ;  //OCT or OCR Output Control Registerinit_addr[4 ]<=8'h00 ;  //CDR Clock Driver Registerinit_addr[5 ]<=8'h00 ;   //ACRN0 Acceptance Code Registersinit_addr[6 ]<=8'h00 ;   //ACRN1init_addr[7 ]<=8'h00 ;   //ACRN2init_addr[8 ]<=8'h00 ;   //ACRN3init_addr[9 ]<=8'h00 ;   //AMR0 Acceptance Mask Registersinit_addr[10]<=8'h00 ;   //AMR1init_addr[11]<=8'h00 ;   //AMR2init_addr[12]<=8'h00 ;	 //AMR3init_addr[13]<=8'h00 ;	 //MODendelse begininit_addr[0 ]<=8'h00 ;  //MOD     ????SJA1000??????init_addr[1 ]<=8'h06 ;  //TIMER0init_addr[2 ]<=8'h07 ;  //TIMER1init_addr[3 ]<=8'h08 ;  //OCT or OCR Output Control Registerinit_addr[4 ]<=8'h1F ;  //CDR Clock Driver Registerinit_addr[5 ]<=8'h10 ;   //ACRN0 Acceptance Code Registersinit_addr[6 ]<=8'h11 ;   //ACRN1init_addr[7 ]<=8'h12 ;   //ACRN2init_addr[8 ]<=8'h13 ;   //ACRN3init_addr[9 ]<=8'h14 ;   //AMR0 Acceptance Mask Registersinit_addr[10]<=8'h15 ;   //AMR1init_addr[11]<=8'h16 ;   //AMR2init_addr[12]<=8'h17 ;	 //AMR3init_addr[13]<=8'h00 ;	 //MODend      
endalways @(posedge clk_in) begin //?14?data     if (reset) begin                     init_data[0 ]<=8'h00 ;  //reset_modelinit_data[1 ]<=8'h00 ;  // bps1/2  clk_in=40mhz init_data[2 ]<=8'h5c ;  // cycle da20  500kbps//init_data[1] <= 8'h00; //bps Fosc = 16MHz//init_data[2] <= 8'h00; //800kbps //??T_seg1 = 7 ? T_seg2 = 2??init_data[3]<=8'h00;  // oct output 8'h0001_1010init_data[4 ]<=8'h00;	// CDR.7=1 pelican model CDR.3=1  close out_clk_in//init_data[5 ]<=8'h04 ;  // receive only  ID=04 frame //??? receive only ID=04 frameinit_data[5 ]<=8'h00 ;init_data[6 ]<=8'h00 ;  //???????????? ?sja1000?ID?? ????sja1000??init_data[7 ]<=8'h00 ;  //???????????? ?sja1000?ID?? ????sja1000??init_data[8 ]<=8'h00 ;  //???????????? ?sja1000?ID?? ????sja1000??//init_data[9 ]<=8'h03 ;  //???????????? ?sja1000?ID?? ????sja1000??init_data[9 ]<=8'h00 ;  //???????????? ?sja1000?ID?? ????sja1000??init_data[10]<=8'h00 ;  //???????????? ?sja1000?ID?? ????sja1000??init_data[11]<=8'h00 ;  //???????????? ?sja1000?ID?? ????sja1000??init_data[12]<=8'h00 ;  //???????????? ?sja1000?ID?? ????sja1000??init_data[13]<=8'h00 ;  // normal modelend else begininit_data[0 ]<=8'h09 ;  //reset_modelinit_data[1 ]<=8'h00 ;  // bps1/2  clk_in=40mhz init_data[2 ]<=8'h5c ;  // cycle da20  500kbps//init_data[1] <= 8'h00; //bps Fosc = 16MHz//init_data[2] <= 8'h16; //800kbps //??T_seg1 = 7 ? T_seg2 = 2??init_data[3 ]<=8'h1A ;  // oct output 8'h0001_1010init_data[4 ]<=8'hC8 ;	// CDR.7=1 pelican model CDR.3=1  close out_clk_in//init_data[5 ]<=8'h04 ;  // receive only  ID=04 frame //??? receive only ID=04 frameinit_data[5 ]<=8'h04 ;   // receive  ID=04 frame ID 10:3   init_data[6 ]<=8'hE0 ;  //receive  ID=04 frame  ID 2:0  ID?0000_0100_111 RTR?0init_data[7 ]<=8'h00 ;  //???????????? ?sja1000?ID?? ????sja1000??init_data[8 ]<=8'h00 ;  //???????????? ?sja1000?ID?? ????sja1000??//init_data[9 ]<=8'h03 ;  //???????????? ?sja1000?ID?? ????sja1000??init_data[9 ]<=8'h00 ;  //???????????? ?sja1000?ID?? ????sja1000??init_data[10]<=8'h1F ;  //???????????? ?sja1000?ID?? ????sja1000??init_data[11]<=8'hFF ;  //???????????? ?sja1000?ID?? ????sja1000??init_data[12]<=8'hFF ;  //???????????? ?sja1000?ID?? ????sja1000??init_data[13]<=8'h08 ;  // normal modelend
end
//
always @(posedge clk_in) begin //??13?addr//14-26 //??14 15bit(?8'h0E, 8'h0F)?rx?tx?error counter??op mode??????//?????(EFF)?????rx_tx_addr???8'h1Cif (reset) beginrx_tx_addr[0 ]<=8'h00; rx_tx_addr[1 ]<=8'h00; rx_tx_addr[2 ]<=8'h00; rx_tx_addr[3 ]<=8'h00; rx_tx_addr[4 ]<=8'h00; rx_tx_addr[5 ]<=8'h00; rx_tx_addr[6 ]<=8'h00; rx_tx_addr[7 ]<=8'h00; rx_tx_addr[8 ]<=8'h00; rx_tx_addr[9 ]<=8'h00; rx_tx_addr[10]<=8'h00; rx_tx_addr[11]<=8'h00;rx_tx_addr[12]<=8'h00;rx_tx_addr[13]<=8'h00;rx_tx_addr[14]<=8'h00;endelse beginrx_tx_addr[0 ]<=8'h10 ; rx_tx_addr[1 ]<=8'h11 ; rx_tx_addr[2 ]<=8'h12 ; rx_tx_addr[3 ]<=8'h13 ; rx_tx_addr[4 ]<=8'h14 ; rx_tx_addr[5 ]<=8'h15 ; rx_tx_addr[6 ]<=8'h16 ; rx_tx_addr[7 ]<=8'h17 ; rx_tx_addr[8 ]<=8'h18 ; rx_tx_addr[9 ]<=8'h19 ; rx_tx_addr[10]<=8'h1A ; rx_tx_addr[11]<=8'h1B ;rx_tx_addr[12]<=8'h1C ;rx_tx_addr[13]<=8'h0E ;rx_tx_addr[14]<=8'h0F ;//rx_tx_addr[11]<=8'h0E ; //rx_tx_addr[12]<=8'h0F ; end 
end//???EFF?????????
always @(posedge clk_in) beginif (reset)send_flag <= 1'b0;else if(CAN_DATA_SEND_DONE)send_flag  <=1'b0;else if(CAN_DATA_SEND_EN) beginsend_flag  <= 1'b1;//SFFtx_data[0 ] <= CAN_ID0_tx   ; tx_data[1 ] <= CAN_ID1_tx   ; tx_data[2 ] <= CAN_ID2_tx   ; tx_data[3 ] <= CAN_DATA1_tx ; tx_data[4 ] <= CAN_DATA2_tx ; tx_data[5 ] <= CAN_DATA3_tx ; tx_data[6 ] <= CAN_DATA4_tx ; tx_data[7 ] <= CAN_DATA5_tx ; tx_data[8 ] <= CAN_DATA6_tx ; tx_data[9 ] <= CAN_DATA7_tx ; tx_data[10] <= CAN_DATA8_tx ; //EFF/*tx_data[0 ] <= CAN_ID0_tx   ; tx_data[1 ] <= CAN_ID1_tx   ; tx_data[2 ] <= CAN_ID2_tx   ; tx_data[3 ] <= CAN_ID3_tx	  ; tx_data[4 ] <= CAN_ID4_tx	  ; tx_data[5 ] <= CAN_DATA1_tx ; tx_data[6 ] <= CAN_DATA2_tx ; tx_data[7 ] <= CAN_DATA3_tx ; tx_data[8 ] <= CAN_DATA4_tx ; tx_data[9 ] <= CAN_DATA5_tx ; tx_data[10] <= CAN_DATA6_tx ; tx_data[11] <= CAN_DATA7_tx ;tx_data[12] <= CAN_DATA8_tx ;*/end elsesend_flag <= send_flag;
end(*KEEP = "TRUE"*) reg send_flag_r;
(*KEEP = "TRUE"*) wire pos = (send_flag && (!send_flag_r)) ; //for watching
always @ (posedge clk_in) beginif (reset)send_flag_r <= 1'b0;elsesend_flag_r <= send_flag;
end//ALL state //?????
//parameter          INIT_RESET =5'b00001,
//                    INIT       =5'b00010,
//				    IDLE       =5'b00100,
//				    DATA_READ  =5'b01000,
//				    DATA_SEND  =5'b10000;//reg [4:0]    state_c,state_n;
always @(posedge clk_in ) beginif((reset)||(!init_restf))begin state_c<=INIT_RESET;end elsebeginstate_c<=state_n;end 
endalways @(*) beginif((reset)||(!init_restf))state_n<=INIT_RESET;else case(state_c)//init_restf ?????????FPGA up?? SJA1000???up//init_restf means initialize reset finished INIT_RESET: if(init_restf)state_n<=INIT;elsestate_n<=INIT_RESET;//?????????(initialize)INIT      : if(init_finish)state_n<=IDLE;elsestate_n<=INIT;IDLE      :if(need_reset)state_n<=INIT_RESET;else if(need_read)state_n<=DATA_READ;else if(need_send)state_n<=DATA_SEND;elsestate_n<=IDLE;DATA_READ  : if(read_finish)//????need_resetstate_n<=IDLE;elsestate_n<=DATA_READ;			DATA_SEND  :if(need_reset)state_n<=INIT_RESET;else if(send_finish)state_n<=IDLE;elsestate_n<=DATA_SEND;default    :  state_n<=INIT_RESET;endcaseend
//*************************************************state=INIT_RESET**********************************//*******************************???????????sja1000????***************************************************************************			   
parameter WAIT_FOR_SJA_UP = 16'd20000; //400
parameter AFTER_WAIT = 16'd30000; //420always @(posedge clk_in ) beginif(reset||(re_config))begin init_restf<=1'b0;//cnt       <=10'd0;cnt <= 16'd0;CAN_RST   <=1'b0;end//????state_n????????state_c?????????????else if (state_n == INIT_RESET) beginif (cnt < WAIT_FOR_SJA_UP) begincnt<=cnt+1'b1;CAN_RST<=1'b0;init_restf<=1'b0;endelse if ((cnt >= WAIT_FOR_SJA_UP ) && (cnt < AFTER_WAIT)) begincnt<=cnt+1'b1;CAN_RST<=1'b1;init_restf<=1'b0;endelse begincnt <= cnt;CAN_RST<=1'b1;init_restf<=1'b1;endendelse begincnt <= cnt;CAN_RST<=1'b1;init_restf<=1'b1;endend
//***********************************************************************************************************
//??5s????sja1000??? or sja1000??????????90?
//or ???????? ?????sja1000  
assign        need_reset = ((reset_cnt>=32'd200000000) 	|| 	//?????????????????(idle_sr_data[7])			||	//SR.7 == 0 ?? bus on  (CAN_RXERR_rx>=8'd90)		||(CAN_TXERR_rx>=8'd90)		); // ? 1'b1 : 1'b0;always @(posedge clk_in ) beginif(reset||(re_config)||(!init_restf))reset_cnt<=32'd0;else  if((state_n==DATA_READ)||(state_n==INIT_RESET))reset_cnt<=32'd0;else if(can_auto_reset)reset_cnt<=reset_cnt+1'b1;elsereset_cnt<=32'd0;  
end
//*************************************************************************************************************
//init_state initial all sja1000 registers
//*************************************************************************************************************always @(posedge clk_in ) beginif((reset)||(!init_restf))begin init_act_path  <=1'b0;init_state     <=3'b001;init_cnt       <=4'd0;init_write0    <=1'b0;init_finish    <=1'b0;init_addr_path<=8'h00;init_data_path<=8'h00;end else case(init_state)3'b001: if(state_n==INIT)begin init_state<=3'b010;init_finish<=1'b0;end else begin init_cnt<=4'd0;init_state<=3'b001;init_act_path<=1'b0;init_write0<=1'b0  ;init_finish<=1'b0;end 3'b010: if(send_done_path)begininit_act_path<=1'b0;init_cnt<=init_cnt+1'b1;init_state<=3'b100;init_write0<=1'b0;end else begin//? rs_port ??act ? write0 ???????????init_act_path<=1'b1;init_addr_path<=init_addr[init_cnt];init_data_path<=init_data[init_cnt];init_write0<=1'b1;init_state<=3'b010;end 3'b100:if(init_cnt<14)begin init_finish<=1'b0;init_state<=3'b010;end elsebegin init_state<=3'b001;init_finish<=1'b1;end default :  begin init_cnt<=4'd0;init_state<=3'b001;init_act_path<=1'b0;init_write0<=1'b0  ;init_finish<=1'b0;end endcase     end
//*************************************************************************************************************
//IDLE state read sr_register and judge read or write 
//*************************************************************************************************************							 always @(posedge clk_in ) beginif((reset)||(!init_restf))begin idle_act_path<=1'b0	;idle_state   <=3'b001;need_read    <=1'b0 	;need_send    <=1'b0  ;idle_write0  <=1'b0  ;idle_sr_data <=8'h00 ;end else case(idle_state)3'b001: if(state_n==IDLE)//???idle???????SRbegin idle_state<=3'b010;idle_act_path<=1'b1;//act=1,write0=0 means readidle_write0<=1'b0  ;idle_addr_path<=8'h02;idle_sr_data <=8'h00 ;need_read<=1'b0;need_send<=1'b0;end else begin idle_state<=3'b001;idle_act_path<=1'b0;idle_write0<=1'b0  ;idle_addr_path<=8'h02;need_read<=1'b0;need_send<=1'b0;end 3'b010: if(recv_done_path)beginidle_act_path<=1'b0;idle_state<=3'b100;idle_write0<=1'b0;idle_sr_data<=recv_data_path;end else beginidle_act_path<=1'b1;idle_write0<=1'b0;idle_state<=3'b010;idle_addr_path<=8'h02;end //judge 3'b100:  if(idle_sr_data[0])//SR.0 == 1 means receive buffer is fullbegin need_read<=1'b1;need_send<=1'b0;idle_state<=3'b001;end else if({idle_sr_data[5],idle_sr_data[4],idle_sr_data[2],send_flag}==4'b0011)//??????????????//SR.5 == 1 means transmitting a message, 0 is IDLE//SR.4 == 1 means receiving a message, 0 is IDLE//SR.2 == 1 means note that the CPU may write a message into the transmit bufferbegin need_read<=1'b0;need_send<=1'b1;idle_state<=3'b001;end elsebegin need_read<=1'b0;need_send<=1'b0;idle_state<=3'b001;enddefault :     idle_state<=3'b001;	endcase							  end	            //******************************************************************************************************************************************
//*************************************************************************************************************
//DATA_READ state do read and clear fifo
//*************************************************************************************************************							 //**************************************************************						always @(posedge clk_in ) beginif((reset)||(!init_restf))begin read_act_path<=1'b0;read_state   <=3'b001;read_write0  <=1'b0  ;CAN_DATA_RECV_DONE<=1'b0;read_finish   <=1'b0  ;read_cnt   <=4'd0;//read_data_path<=8'h04; //clear receive bufferCAN_RXERR_rx<=8'h00;CAN_TXERR_rx<=8'h00;DATA_RECEIVE_DO<=1'b0;read_addr_path <= 8'h00;read_data_path <= 8'h00;end else  case(read_state)3'b001: if(state_n==DATA_READ)beginread_state<=3'b010;read_act_path<=1'b1;read_write0<=1'b0  ;read_addr_path<=rx_tx_addr[read_cnt];CAN_DATA_RECV_DONE<=1'b0;read_finish   <=1'b0  ;end else begin read_state<=3'b001;read_act_path<=1'b0;read_write0<=1'b0  ;read_addr_path<=rx_tx_addr[read_cnt];read_data_path<=8'h00;//new addingread_cnt   <=4'd0;CAN_DATA_RECV_DONE<=1'b0;read_finish   <=1'b0  ;end 3'b010: if(recv_done_path)beginread_act_path<=1'b0;read_state<=3'b100;read_write0<=1'b0;read_cnt <= read_cnt + 1'b1;//????1end else beginread_act_path<=1'b1;read_write0<=1'b0;read_state<=3'b010;end 3'b100:  //if (read_cnt < 15)if (read_cnt < (rx_DLC + 6)) begin  //rx_DLC + 6 ?????14case (rx_DLC) 'd0 : begincase (read_cnt)'d1 : begin CAN_ID0_rx  <= recv_data_path;   end'd2 : begin CAN_ID1_rx  <= recv_data_path;   end'd3 : begin CAN_ID2_rx  <= recv_data_path;   end'd4 : begin CAN_ID3_rx  <= recv_data_path;   end'd5 : begin CAN_ID4_rx  <= recv_data_path; DATA_RECEIVE_DO <= 1'b1; read_cnt<=4'd13;enddefault: read_state<=3'b001;endcaseend'd1: begin case (read_cnt)'d1 : begin CAN_ID0_rx  <= recv_data_path;   end'd2 : begin CAN_ID1_rx  <= recv_data_path;   end'd3 : begin CAN_ID2_rx  <= recv_data_path;   end'd4 : begin CAN_ID3_rx  <= recv_data_path;   end'd5 : begin CAN_ID4_rx  <= recv_data_path;   end'd6 : begin CAN_DATA1_rx <= recv_data_path; DATA_RECEIVE_DO <= 1'b1;read_cnt<=4'd13;enddefault:read_state<=3'b001;endcaseend'd2: begincase (read_cnt)'d1 : begin CAN_ID0_rx  <= recv_data_path;   end'd2 : begin CAN_ID1_rx  <= recv_data_path;   end'd3 : begin CAN_ID2_rx  <= recv_data_path;   end'd4 : begin CAN_ID3_rx  <= recv_data_path;   end'd5 : begin CAN_ID4_rx  <= recv_data_path;   end'd6 : begin CAN_DATA1_rx <= recv_data_path;  end'd7 : begin CAN_DATA2_rx <= recv_data_path; DATA_RECEIVE_DO <= 1'b1; read_cnt<=4'd13;enddefault:read_state<=3'b001;endcaseend'd3 : begincase (read_cnt)'d1 : begin CAN_ID0_rx  <= recv_data_path;   end'd2 : begin CAN_ID1_rx  <= recv_data_path;   end'd3 : begin CAN_ID2_rx  <= recv_data_path;   end'd4 : begin CAN_ID3_rx  <= recv_data_path;   end'd5 : begin CAN_ID4_rx  <= recv_data_path;   end'd6 : begin CAN_DATA1_rx <= recv_data_path;  end'd7 : begin CAN_DATA2_rx <= recv_data_path;  end'd8 : begin CAN_DATA3_rx <= recv_data_path; DATA_RECEIVE_DO <= 1'b1;read_cnt<=4'd13;enddefault:read_state<=3'b001;endcaseend'd4 : begincase (read_cnt)'d1 : begin CAN_ID0_rx  <= recv_data_path;  end'd2 : begin CAN_ID1_rx  <= recv_data_path;  end'd3 : begin CAN_ID2_rx  <= recv_data_path;  end'd4 : begin CAN_ID3_rx  <= recv_data_path;  end'd5 : begin CAN_ID4_rx  <= recv_data_path;  end'd6 : begin CAN_DATA1_rx <= recv_data_path; end'd7 : begin CAN_DATA2_rx <= recv_data_path; end'd8 : begin CAN_DATA3_rx <= recv_data_path; end'd9 : begin CAN_DATA4_rx <= recv_data_path; DATA_RECEIVE_DO <= 1'b1;read_cnt<=4'd13; enddefault:read_state<=3'b001;endcaseend'd5 : begincase (read_cnt)'d1 : begin CAN_ID0_rx  <= recv_data_path;  end'd2 : begin CAN_ID1_rx  <= recv_data_path;  end'd3 : begin CAN_ID2_rx  <= recv_data_path;  end'd4 : begin CAN_ID3_rx  <= recv_data_path;  end'd5 : begin CAN_ID4_rx  <= recv_data_path;  end'd6 : begin CAN_DATA1_rx <= recv_data_path; end'd7 : begin CAN_DATA2_rx <= recv_data_path; end'd8 : begin CAN_DATA3_rx <= recv_data_path; end'd9 : begin CAN_DATA4_rx <= recv_data_path; end'd10: begin CAN_DATA5_rx <= recv_data_path; DATA_RECEIVE_DO <= 1'b1; read_cnt<=4'd13;enddefault:read_state<=3'b001;endcaseend'd6 : begincase (read_cnt)'d1 : begin CAN_ID0_rx  <= recv_data_path;  end'd2 : begin CAN_ID1_rx  <= recv_data_path;  end'd3 : begin CAN_ID2_rx  <= recv_data_path;  end'd4 : begin CAN_ID3_rx  <= recv_data_path;  end'd5 : begin CAN_ID4_rx  <= recv_data_path;  end'd6 : begin CAN_DATA1_rx <= recv_data_path; end'd7 : begin CAN_DATA2_rx <= recv_data_path; end'd8 : begin CAN_DATA3_rx <= recv_data_path; end'd9 : begin CAN_DATA4_rx <= recv_data_path; end'd10: begin CAN_DATA5_rx <= recv_data_path; end'd11: begin CAN_DATA6_rx <= recv_data_path; DATA_RECEIVE_DO <= 1'b1; read_cnt<=4'd13;enddefault:read_state<=3'b001;endcaseend'd7 : begincase (read_cnt)'d1 : begin CAN_ID0_rx  <= recv_data_path;  end'd2 : begin CAN_ID1_rx  <= recv_data_path;  end'd3 : begin CAN_ID2_rx  <= recv_data_path;  end'd4 : begin CAN_ID3_rx  <= recv_data_path;  end'd5 : begin CAN_ID4_rx  <= recv_data_path;  end'd6 : begin CAN_DATA1_rx <= recv_data_path; end'd7 : begin CAN_DATA2_rx <= recv_data_path; end'd8 : begin CAN_DATA3_rx <= recv_data_path; end'd9 : begin CAN_DATA4_rx <= recv_data_path; end'd10: begin CAN_DATA5_rx <= recv_data_path; end'd11: begin CAN_DATA6_rx <= recv_data_path; end'd12: begin CAN_DATA7_rx <= recv_data_path; DATA_RECEIVE_DO <= 1'b1; read_cnt<=4'd13;enddefault:read_state<=3'b001;endcaseend'd8 : begincase (read_cnt)'d1 : begin CAN_ID0_rx  <= recv_data_path;  end'd2 : begin CAN_ID1_rx  <= recv_data_path;  end'd3 : begin CAN_ID2_rx  <= recv_data_path;  end'd4 : begin CAN_ID3_rx  <= recv_data_path;  end'd5 : begin CAN_ID4_rx  <= recv_data_path;  end'd6 : begin CAN_DATA1_rx <= recv_data_path; end'd7 : begin CAN_DATA2_rx <= recv_data_path; end'd8 : begin CAN_DATA3_rx <= recv_data_path; end'd9 : begin CAN_DATA4_rx <= recv_data_path; end'd10: begin CAN_DATA5_rx <= recv_data_path; end'd11: begin CAN_DATA6_rx <= recv_data_path; end'd12: begin CAN_DATA7_rx <= recv_data_path; end'd13: begin CAN_DATA8_rx <= recv_data_path; DATA_RECEIVE_DO <= 1'b1; read_cnt<=4'd13;enddefault:read_state<=3'b001;endcaseenddefault : read_state <= 3'b001;endcase//read_cnt 	 <= 4'd13; read_state <= 3'b001;endelse if (read_cnt == 4'd14) beginCAN_RXERR_rx <= recv_data_path; read_state <= 3'b001; endelse  begin //??SFF??read_cnt = 13, ???rx_tx_addr[12] = 8'h0F;//????????TXERR????????...read_state<=3'b101;read_cnt<=4'd0 ;read_addr_path<=8'h01; //write cmd to clear RB(receive buffer)read_data_path<=8'h04; //clear receive bufferread_write0<=1'b1;read_act_path<=1'b1;CAN_TXERR_rx<=recv_data_path;//TXERRCAN_DATA_RECV_DONE<=1'b1;//?? DATA_RECEIVE_DO = 1end 3'b101:  if(send_done_path)begin read_state<=3'b001;CAN_DATA_RECV_DONE<=1'b0;DATA_RECEIVE_DO<=1'b0;read_finish<=1'b1;read_act_path<=1'b0;read_write0 <=1'b0;end else  begin read_state<=3'b101;CAN_DATA_RECV_DONE<=1'b0;DATA_RECEIVE_DO<=1'b0;read_finish<=1'b0;read_write0<=1'b1;read_act_path<=1'b1;end default :     read_state<=3'b001;								endcaseend
//******************************************************************************************************************************************
//******************************************************************************************************************************************
//*************************************************************************************************************
//send
//*************************************************************************************************************							 always @(posedge clk_in) beginif((reset)||(!init_restf))begin send_act_path<=1'b0;send_state   <=3'b001;send_write0  <=1'b0  ;CAN_DATA_SEND_DONE<=1'b0;send_finish   <=1'b0  ;send_cnt      <=4'd0  ;send_addr_path <= 8'h00;send_data_path <= 8'h00;end else case(send_state)3'b001: if(state_n==DATA_SEND)begin send_state<=3'b010;send_act_path<=1'b1;send_write0<=1'b1  ;send_addr_path<=rx_tx_addr[send_cnt];send_data_path<=tx_data[send_cnt];CAN_DATA_SEND_DONE<=1'b0;send_finish <=1'b0  ;end else begin send_state<=3'b001;send_act_path<=1'b0;send_write0<=1'b1  ;send_addr_path<=rx_tx_addr[send_cnt];send_data_path<=tx_data[send_cnt];send_cnt   <=4'd0;CAN_DATA_SEND_DONE<=1'b0;send_finish   <=1'b0  ;end 3'b010: if(send_done_path)beginsend_act_path<=1'b0;send_state<=3'b100;send_write0<=1'b0;send_cnt <=send_cnt+1'b1;end else beginsend_act_path<=1'b1;send_write0<=1'b1;send_state<=3'b010;end 3'b100:  //if(send_cnt<11)//SFF//if (send_cnt < 13)//EFF //??if (send_cnt < (tx_DLC + 5))send_state<=3'b001;elsebegin send_cnt<=4'd0;//tx_dataCAN_DATA_SEND_DONE<=1'b0;send_state<=3'b101; send_act_path<=1'b1;send_write0<=1'b1;send_addr_path<=8'h01;send_data_path<=8'h01;  //send cmd//????????SJA1000??????end //send_addr_path<=8'h01; send_data_path<=8'h01; ???????????TX buffer????????CMR???????3'b101:   if(send_done_path) begin send_state<=3'b001;CAN_DATA_SEND_DONE<=1'b1;send_finish <=1'b1;send_act_path<=1'b0;send_write0<=1'b1;end  else 	begin send_state<=3'b101;CAN_DATA_SEND_DONE<=1'b0;send_finish <=1'b0;send_act_path<=1'b1;send_write0<=1'b1;end  										 default :     send_state<=3'b001;								endcaseend//******************************************************************************************
//MUX the data_path
//*******************************************************************************************
//*******************************************************************************************
always @(*) beginif((reset)||(!init_restf))begin act            <=1'b0;write0         <=1'b0;need_addr_path <=8'd0;s_data_path    <=8'd0;end else case(state_n)INIT_RESET :  begin act            <=1'b0;write0         <=1'b0;need_addr_path <=8'd0;s_data_path    <=8'd0;end INIT       :  begin act           <=init_act_path;write0        <=init_write0  ;need_addr_path<=init_addr_path;s_data_path   <=init_data_path;end 		 IDLE       :  begin act           <= idle_act_path;write0        <= idle_write0  ;need_addr_path<= idle_addr_path;s_data_path   <= 8'd0;end 		 DATA_READ  : begin act           <= read_act_path;write0        <= read_write0  ;need_addr_path<= read_addr_path;s_data_path   <= read_data_path;end DATA_SEND  :begin act            <=  send_act_path ;write0         <=  send_write0   ;need_addr_path <=  send_addr_path;s_data_path    <=  send_data_path;end default     :begin     act            <=1'b0;write0         <=1'b0;need_addr_path <=8'd0;s_data_path    <=8'd0;end endcaseend//module rs_port list
rs_port u1(.clk       (clk_in        ),    .reset     (((reset)|(!init_restf))),      .act       (act           ),         .write0    (write0        ),         .need_addr (need_addr_path),.recv_data (recv_data_path),.recv_done (recv_done_path),.send_data (s_data_path   ),.send_done (send_done_path),.ALE       (CAN_ALE       ), .WR        (CAN_WR        ), .RD        (CAN_RD        ), .CS        (CAN_CS        ),               .DATA_CAN  (DATA_CAN      ),.en       (en            )	
);endmodule 


http://www.ppmy.cn/devtools/132434.html

相关文章

Unity性能优化 -- 性能分析工具

Stats窗口Profiler窗口Memory Profiler其他性能分析工具&#xff08;Physica Debugger 窗口&#xff0c;Import Activity 窗口&#xff0c;Code Coverage 窗口&#xff0c;Profile Analyzer 窗口&#xff0c;IMGUI Debugger 窗口&#xff09; Stats 统级数据窗口 game窗口 可…

用示例来看C2Rust工具的使用和功能介绍

C2Rust可以将C语言的源代码转换成Rust语言的源代码。下面是一个简单的C语言代码示例,以及使用c2Rust工具将其转换为Rust安全代码的过程。 C语言源代码示例 // example.c #include <stdio.h>int add(int a, int b)

leetcode203. Remove Linked List Elements

给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 Given the head of a linked list and an integer val, remove all the nodes of the linked list that has Node.val val, and return …

git原理与上传

言&#xff1a; git是一个软件&#xff0c;gitee/github是一个网站&#xff0c;这里有什么联系吗&#xff1f;我们身为一个程序员不可能不知道github&#xff0c;但是毕竟这是外国的网站&#xff0c;我们不翻墙的情况下&#xff0c;是无法访问的(或者就是太慢了&#xff0c;或…

Solana 代币 2022 — Transfer Hook

从零到英雄的 Solana 代币 2022 — Transfer Hook Token 2022 计划引入了几项令人兴奋的扩展&#xff0c;增强了铸造和代币账户的功能。在这些功能中&#xff0c;我个人最喜欢的是Transfer Hook &#xff08;转账钩子&#xff09; 。 想象时间 让我们戴上想象的帽子&#xf…

【系统架构设计师】高分论文:论软件的可用性设计

更多内容请见: 备考系统架构设计师-专栏介绍和目录 文章目录 摘要正文摘要 2021年5月,我参加了某市人才集团信息化集中项目的建设。在该项目中,我担任系统架构师。该项目合同金额为 523.5 万元,建设工期为8个月,项目建设内容包含新建一个门户网站、新建4个子系统以及集成…

腾讯为什么支持开源?

今天看到一条新闻&#xff0c;感觉腾讯在 AI 大模型方面确实挺厉害的&#xff0c;符合它低调务实的风格&#xff0c;在不知不觉中一天竟然开源了两个核心的&#xff0c;重要的 AI 大模型。 据新闻报道&#xff0c;11月 5 日&#xff0c;腾讯混元宣布最新的 MoE 模型“混元 Larg…

window10解决 docker is starting 问题

win10 需要开启 Hyper-V。 在程序和功能中开启服务Server (不开启的话&#xff0c;安装完会报错) 安装toolbox 最新版 Toolbox 下载地址&#xff1a; 访问 https://www.docker.com/get-started&#xff0c;注册一个账号&#xff0c;然后登录。 点击 Get started with Docke…