|
| 1 | +library IEEE; |
| 2 | +use IEEE.STD_LOGIC_1164.ALL; |
| 3 | +use IEEE.NUMERIC_STD.ALL; |
| 4 | + |
| 5 | +entity can_controller is |
| 6 | + Port ( |
| 7 | + clk : in STD_LOGIC; |
| 8 | + rst : in STD_LOGIC; |
| 9 | + rx : in STD_LOGIC; |
| 10 | + tx : out STD_LOGIC; |
| 11 | + data_in : in STD_LOGIC_VECTOR(63 downto 0); |
| 12 | + data_out : out STD_LOGIC_VECTOR(63 downto 0); |
| 13 | + data_valid : out STD_LOGIC |
| 14 | + ); |
| 15 | +end can_controller; |
| 16 | + |
| 17 | +architecture Behavioral of can_controller is |
| 18 | + type can_state_type is (IDLE, ARBITRATION, CONTROL, DATA, CRC, ACK, EOF); |
| 19 | + signal state : can_state_type := IDLE; |
| 20 | + signal bit_counter : integer range 0 to 127 := 0; |
| 21 | + signal crc : STD_LOGIC_VECTOR(14 downto 0) := (others => '0'); |
| 22 | + |
| 23 | + -- CAN frame components |
| 24 | + signal arbitration_field : STD_LOGIC_VECTOR(11 downto 0); |
| 25 | + signal control_field : STD_LOGIC_VECTOR(5 downto 0); |
| 26 | + signal data_field : STD_LOGIC_VECTOR(63 downto 0); |
| 27 | + |
| 28 | +begin |
| 29 | + process(clk, rst) |
| 30 | + begin |
| 31 | + if rst = '1' then |
| 32 | + state <= IDLE; |
| 33 | + bit_counter <= 0; |
| 34 | + crc <= (others => '0'); |
| 35 | + tx <= '1'; |
| 36 | + data_valid <= '0'; |
| 37 | + elsif rising_edge(clk) then |
| 38 | + case state is |
| 39 | + when IDLE => |
| 40 | + if rx = '0' then -- Start of Frame detected |
| 41 | + state <= ARBITRATION; |
| 42 | + bit_counter <= 0; |
| 43 | + end if; |
| 44 | + |
| 45 | + when ARBITRATION => |
| 46 | + if bit_counter < 11 then |
| 47 | + arbitration_field(11 - bit_counter) <= rx; |
| 48 | + bit_counter <= bit_counter + 1; |
| 49 | + else |
| 50 | + state <= CONTROL; |
| 51 | + bit_counter <= 0; |
| 52 | + end if; |
| 53 | + |
| 54 | + when CONTROL => |
| 55 | + if bit_counter < 6 then |
| 56 | + control_field(5 - bit_counter) <= rx; |
| 57 | + bit_counter <= bit_counter + 1; |
| 58 | + else |
| 59 | + state <= DATA; |
| 60 | + bit_counter <= 0; |
| 61 | + end if; |
| 62 | + |
| 63 | + when DATA => |
| 64 | + if bit_counter < 64 then |
| 65 | + data_field(63 - bit_counter) <= rx; |
| 66 | + bit_counter <= bit_counter + 1; |
| 67 | + else |
| 68 | + state <= CRC; |
| 69 | + bit_counter <= 0; |
| 70 | + end if; |
| 71 | + |
| 72 | + when CRC => |
| 73 | + if bit_counter < 15 then |
| 74 | + crc(14 - bit_counter) <= rx; |
| 75 | + bit_counter <= bit_counter + 1; |
| 76 | + else |
| 77 | + state <= ACK; |
| 78 | + bit_counter <= 0; |
| 79 | + end if; |
| 80 | + |
| 81 | + when ACK => |
| 82 | + if bit_counter = 0 then |
| 83 | + tx <= '0'; -- Send ACK |
| 84 | + bit_counter <= bit_counter + 1; |
| 85 | + elsif bit_counter = 1 then |
| 86 | + tx <= '1'; -- ACK delimiter |
| 87 | + bit_counter <= 0; |
| 88 | + state <= EOF; |
| 89 | + end if; |
| 90 | + |
| 91 | + when EOF => |
| 92 | + if bit_counter < 7 then |
| 93 | + bit_counter <= bit_counter + 1; |
| 94 | + else |
| 95 | + state <= IDLE; |
| 96 | + bit_counter <= 0; |
| 97 | + data_out <= data_field; |
| 98 | + data_valid <= '1'; |
| 99 | + end if; |
| 100 | + end case; |
| 101 | + end if; |
| 102 | + end process; |
| 103 | + |
| 104 | +end Behavioral; |
0 commit comments