blob: a14bbc5250f4f0b73ed4fd4146bda1dd9db14878 [file] [log] [blame]
// MIT License
// Copyright (c) [2022] [Yonga Technology Microelectronics R&D]
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
// DESCRIPTION
// The yonga_can_controller module manages the operations in CAN peripheral
module yonga_can_controller(
input wire i_controller_clk,
input wire i_controller_rst,
input wire i_pulse_gen_synced,
input wire i_packetizer_rdy,
input wire i_ack_slot,
output reg o_packetizer_en,
output reg o_pulse_gen_en,
input wire i_packetizer_message_bit,
input wire i_message_bit,
output reg o_message_bit,
input wire i_drive_pulse,
input wire i_sample_pulse,
input wire i_config_enable,
input wire i_sys_ctrl_sts_send,
output reg [2:0] o_sts_code
);
parameter STATE_RESET = 0, STATE_SYNC = 1, STATE_CHECK_IDLE = 2, STATE_DRIVE_DATA = 3, STATE_SAMPLE_DATA = 4, STATE_IFS = 5, STATE_ERROR = 6, STATE_EN_PACKETIZER = 7;
reg done_tx;
reg [2:0] state_reg;
reg bit_transmitted;
reg [5:0] bitcounter_reg;
reg prev_bit_reg;
reg [3:0] consecutive_ones_reg;
reg [3:0] zeros_reg;
reg is_extended, is_standart;
reg is_idle;
always @(posedge i_controller_clk) begin
if(i_controller_rst) begin
state_reg <= STATE_RESET;
o_packetizer_en <= 1'b0;
o_pulse_gen_en <= 1'b0;
o_sts_code <= 3'b0;
o_message_bit <= 1'b1;
done_tx <= 1'b0;
bitcounter_reg <= 6'd0;
consecutive_ones_reg <= 4'd0;
is_standart <= 1'b1;
is_extended <= 1'b0;
zeros_reg <= 4'd0;
prev_bit_reg <= 1'b0;
is_idle <= 1'b0;
end
else begin
case(state_reg)
STATE_RESET: begin
o_sts_code <= 3'b0;
o_message_bit <= 1'b1;
done_tx <= 1'b0;
bitcounter_reg <= 6'd0;
is_standart <= 1'b1;
is_extended <= 1'b0;
if((i_config_enable == 0) && (i_sys_ctrl_sts_send == 1)) begin
state_reg <= STATE_SYNC;
o_pulse_gen_en <= 1'b1;
end
end
STATE_SYNC: begin
if(i_pulse_gen_synced) begin
state_reg <= STATE_CHECK_IDLE;
end
end
STATE_CHECK_IDLE: begin
o_sts_code <= 3'b0;
if(i_sample_pulse) begin
if(~is_idle) begin
prev_bit_reg <= i_message_bit;
if(prev_bit_reg) begin
if(i_message_bit) begin
consecutive_ones_reg <= consecutive_ones_reg + 1;
end
else begin
consecutive_ones_reg <= 4'd0;
end
if(consecutive_ones_reg == 4'd9) begin
consecutive_ones_reg = 4'd0;
state_reg <= STATE_EN_PACKETIZER;
is_idle <= 1'b0;
end
end
end
else begin
state_reg <= STATE_EN_PACKETIZER;
is_idle <= 1'b0;
end
end
end
STATE_EN_PACKETIZER: begin
o_packetizer_en <= 1'b1;
if(i_drive_pulse == 1) begin
state_reg <= STATE_DRIVE_DATA;
end
end
STATE_DRIVE_DATA: begin
if(i_drive_pulse == 1) begin
state_reg <= STATE_SAMPLE_DATA;
if(bitcounter_reg == 13 && i_packetizer_message_bit == 0) begin
is_standart <= 1'b1;
is_extended <= 1'b0;
end
else if(bitcounter_reg == 13 && i_packetizer_message_bit == 1) begin
is_standart <= 1'b0;
is_extended <= 1'b1;
end
bit_transmitted <= i_packetizer_message_bit;
o_message_bit <= i_packetizer_message_bit;
end
end
STATE_SAMPLE_DATA: begin
if(i_sample_pulse == 1) begin
bitcounter_reg <= bitcounter_reg + 1;
prev_bit_reg <= i_message_bit;
if(prev_bit_reg) begin
if(i_message_bit) begin
consecutive_ones_reg <= consecutive_ones_reg + 1;
end
else begin
consecutive_ones_reg <= 4'd0;
end
end
if(bit_transmitted == i_message_bit) begin
if(i_ack_slot) begin
o_sts_code <= 3'h3;
bitcounter_reg <= 0;
o_packetizer_en <= 0;
state_reg <= STATE_IFS;
end
else if(i_packetizer_rdy) begin // EOF flag
o_packetizer_en <= 0;
bitcounter_reg <= 0;
state_reg <= STATE_IFS;
end
else begin
state_reg <= STATE_DRIVE_DATA;
end
end
else begin
if(i_ack_slot == 1) begin
o_sts_code <= 3'h1;
state_reg <= STATE_DRIVE_DATA;
end
else begin
if(is_standart) begin
if(bitcounter_reg < 6'd14) begin // Why 14? SOF + 11 bit standart arbitration field + RTR.
o_sts_code <= 3'h2;
o_packetizer_en <= 0;
state_reg <= STATE_CHECK_IDLE; // Sampled data and transmitted data does not match. Arbitration is lost to another node. STANDART FORMAT
bitcounter_reg <= 6'd0;
end
else begin
o_sts_code <= 3'h2;
o_packetizer_en <= 0;
bitcounter_reg <= 6'd0; // Sampled data and data on bus does not match. Bit error occured. Push eror frame to bus.
state_reg <= STATE_ERROR;
end
end
if(is_extended) begin
if(bitcounter_reg < 6'd34) begin // Why 34? SOF + 32 bit extended arbitration field.
o_sts_code <= 3'h2;
o_packetizer_en <= 0;
state_reg <= STATE_CHECK_IDLE; // Sampled data and transmitted data does not match. Arbitration is lost to another node. EXTENDED FORMAT
bitcounter_reg <= 6'd0;
end
else begin
o_sts_code <= 3'h2;
o_packetizer_en <= 0;
state_reg <= STATE_ERROR; // Sampled data and data on bus does not match. Bit error occured. Push eror frame to bus.
bitcounter_reg <= 6'd0;
end
end
end
end
end
end
STATE_IFS: begin
if(i_drive_pulse == 1'b1) begin
if(bitcounter_reg == 6'd2) begin
bitcounter_reg <= 6'd0;
o_message_bit <= 1;
is_idle <= 1'b1;
consecutive_ones_reg <= consecutive_ones_reg + 1;
done_tx <= 1'b1;
state_reg <= STATE_RESET;
end
else begin
state_reg <= STATE_IFS;
consecutive_ones_reg <= consecutive_ones_reg + 1;
o_message_bit <= 1;
bitcounter_reg <= bitcounter_reg + 1;
end
end
end
STATE_ERROR: begin
state_reg <= STATE_ERROR;
// FILL HERE
end
endcase
end
end
endmodule