使用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