FPGA 基于 SJA1000 的 CAN 总线控制器设计
本项目基于 SJA1000 协议栈,提供 Verilog 和 VHDL 双版本的 CAN 总线控制器实现,支持 Altera 和 Xilinx 工程。代码经过电路板验证,涵盖标准帧与扩展帧处理,并附带仿真激励文件(Testbench)。
代码结构
工程目录包含四个核心模块:状态机控制器、CRC 校验器、位时序单元和 FIFO 缓存。
Verilog 状态机实现
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
VHDL 状态定义
VHDL 版本使用枚举类型定义状态:
type can_state is (SLEEP_MODE, LISTEN_ONLY, ERROR_ACTIVE, ERROR_PASSIVE);
帧格式处理
标准帧和扩展帧的切换通过 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;
Testbench 采用随机间隔发送以复现真实总线负载场景。工程已配置好仿真脚本,可在 Vivado 或 Modelsim 中运行。实测在 Artix-7 上跑 125MHz 时钟,数据吞吐可达 1Mbps。
文档中标注了不同开发板的引脚约束差异,支持 Cyclone IV 和 Spartan-6 等芯片。


