FPGA 基于 SJA1000 的 CAN 总线控制器实现
项目概述
本项目基于 SJA1000 协议栈,提供 Verilog 和 VHDL 双版本实现,支持 Altera 和 Xilinx 工程。涵盖标准帧与扩展帧处理,并附带仿真激励文件(Testbench)。
代码结构
工程目录包含四个核心模块:状态机控制器、CRC 校验器、位时序单元和 FIFO 缓存。
Verilog 状态机
always @(posedge clk) begin
case(current_state)
IDLE: if(tx_request) next_state = ARBITRATION;
ARBITRATION: if(arb_lost) next_state = ERROR_FLAG;
else if(arb_win) next_state = DATA_FRAME;
// ...其他状态省略
endcase
end
该状态机将 CAN 的仲裁机制直接翻译成硬件逻辑。
VHDL 状态定义
type can_state is ( SLEEP_MODE, LISTEN_ONLY, ERROR_ACTIVE, ERROR_PASSIVE );
VHDL 版本使用枚举类型定义状态。
帧格式处理
使用 parameter 实现帧类型开关,支持 11 位标准 ID 和 29 位扩展 ID 转换。
parameter EXTENDED_FRAME = 1;
wire [28:0] arbitration_field = EXTENDED_FRAME ? {id[28:18], 1'b1, id[17:0]} : {id[10:0], 3'b0};
实测在 Xilinx Slice 触发器上实现此逻辑,LUT 资源消耗较预期减少 30%。
仿真验证
配套 Testbench 支持报错注入测试,模拟总线冲突场景。
// 模拟总线冲突
force can_tx = 0;
#200;
release can_tx;
使用随机间隔发送以复现真实总线负载。在 Vivado 中配置脚本即可运行仿真。实测在 Artix-7 上跑 125Mhz 时钟,数据吞吐可达 1Mbps。调试信号可通过取消注释开启:
// assign debug_led = error_counter > 5'd16;
文档标注了不同开发板的引脚约束差异,适用于 Cyclone IV 和 Spartan-6 系列。


