blob: 35625de415eaa367f36cef74d3d8cd5ae44e5c5a [file] [log] [blame]
// File name: ECU.sv
// Created: 5/22/2021
// Author: Zachary Ellis
// Version: 1.0 Initial Design Entry
// Description: CAN error control unit
module ECU (
input bitstrobe,
input tx_strobe,
input nRST,
input curr_sample,
input rx_bitstuff_error,
input rx_form_error,
input rx_crc_error,
input tx_bit_error,
input tx_ack_error,
input [1:0] rx_code,
input [1:0]tx_code,
output start_err_tx,
output reg [8:0] TEC,
output reg [8:0] REC,
output [1:0] error_state,
output reg [2:0] LEC
);
assign error_state[0] = REC[7] | TEC[7];
assign error_state[1] = TEC[8];
assign start_err_tx = rx_bitstuff_error | rx_form_error | rx_crc_error |
tx_bit_error | tx_ack_error;
wire [4:0] error_vec = {rx_bitstuff_error, rx_form_error, rx_crc_error,
tx_bit_error, tx_ack_error};
always @(posedge tx_strobe, negedge nRST) begin
if(nRST == 0) LEC <= '0;
else begin
casez(error_vec)
5'b00001: LEC <= 3'd1;
5'b00010: LEC <= 3'd2;
5'b00100: LEC <= 3'd3;
5'b01?00: LEC <= 3'd4; //weird ACK rules I may have interpreted backwards but function is not impeded
5'b10000: LEC <= 3'd5;
endcase
end
end
reg [8:0] next_REC;
wire idle_period, long_idle;
always_ff @(posedge bitstrobe, negedge nRST) begin
if(nRST == 0) REC <= 0;
else REC <= next_REC;
end
always_comb begin
next_REC = REC;
case(rx_code)
2'b00: next_REC = REC;
2'b01: next_REC = REC + 1;
2'b10: next_REC = REC + 8;
2'b11: begin
if(REC[7]) next_REC = 9'd120;
else if(|REC) next_REC = REC - 1;
end
endcase
if(error_state[1] && long_idle) next_REC = 0;
end
reg [8:0] next_TEC;
always_ff @(posedge tx_strobe, negedge nRST) begin
if(nRST == 0) TEC <= 0;
else TEC <= next_TEC;
end
always_comb begin
next_TEC = TEC;
case(tx_code)
2'b00: next_TEC = TEC;
2'b01: next_TEC = TEC + 1;
2'b10: next_TEC = TEC + 8;
2'b11: if(|TEC) next_TEC = TEC - 1;
endcase
if(TEC[8]) begin
next_TEC = 9'b100000000;
if(long_idle) next_TEC = 0;
end
end
flex_counter #(
.NUM_CNT_BITS(4)
)
U1 (
.clk(bitstrobe),
.n_rst(nRST),
.clear(curr_sample),
.count_enable(1'b1),
.rollover_val(4'd11),
.count_out(),
.rollover_flag(idle_period)
);
flex_counter #(
.NUM_CNT_BITS(8)
)
U2 (
.clk(idle_period),
.n_rst(nRST),
.clear(curr_sample),
.count_enable(1'b1),
.rollover_val(11'd128),
.count_out(),
.rollover_flag(long_idle)
);
endmodule