Initial Commit

This commit is contained in:
Thomas Fehmel
2016-10-18 14:21:45 +02:00
commit 657a54ba18
176 changed files with 43750 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
-- See the file "LICENSE" for the full license governing this code. --
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
USE work.lt16x32_global.all;
USE work.wishbone.all;
USE work.config.all;
ENTITY wb_lcd IS
generic(
memaddr : generic_addr_type;
addrmask : generic_mask_type
);
port(
clk : IN std_logic;
rst : IN std_logic;
dataLCD : INOUT std_logic_vector(7 downto 0);
enableLCD : OUT std_logic;
rsLCD : OUT std_logic;
rwLCD : OUT std_logic;
wslvi : IN wb_slv_in_type;
wslvo : OUT wb_slv_out_type
);
END ENTITY;
ARCHITECTURE behav OF wb_lcd IS
signal lcd_reg : std_logic_vector(10 downto 0);
signal ack : std_logic;
BEGIN
process(clk)
begin
if clk'event and clk='1' then
if rst = '1' then
ack <= '0';
lcd_reg <= (others => '0');
else
if wslvi.stb = '1' and wslvi.cyc = '1' then
if wslvi.we = '1' then
lcd_reg <= dec_wb_dat(wslvi.sel,wslvi.dat)(10 downto 0);
end if;
if ack = '0' then
ack <= '1';
else
ack <= '0';
end if;
else
ack <= '0';
end if;
end if;
end if;
end process;
wslvo.dat(10 downto 0) <= lcd_reg when wslvi.adr(2) = '0'
else "000" & dataLCD when wslvi.adr(2) = '1' and lcd_reg(8) = '1'
else (others => '0');
wslvo.dat(31 downto 11) <= (others=>'0');
wslvo.wbcfg <= wb_membar(memaddr, addrmask);
wslvo.ack <= ack;
enableLCD <= lcd_reg(10);
rsLCD <= lcd_reg(9);
rwLCD <= lcd_reg(8);
dataLCD <= lcd_reg(7 downto 0) when lcd_reg(8) = '0' else "ZZZZZZZZ";
END ARCHITECTURE;

345
soc/peripheral/can_acf.v Normal file
View File

@@ -0,0 +1,345 @@
//////////////////////////////////////////////////////////////////////
//// ////
//// can_acf.v ////
//// ////
//// ////
//// This file is part of the CAN Protocol Controller ////
//// http://www.opencores.org/projects/can/ ////
//// ////
//// ////
//// Author(s): ////
//// Igor Mohor ////
//// igorm@opencores.org ////
//// ////
//// ////
//// All additional information is available in the README.txt ////
//// file. ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2002, 2003, 2004 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//// The CAN protocol is developed by Robert Bosch GmbH and ////
//// protected by patents. Anybody who wants to implement this ////
//// CAN IP core on silicon has to obtain a CAN protocol license ////
//// from Bosch. ////
//// ////
//////////////////////////////////////////////////////////////////////
// synopsys translate_off
// `include "timescale.v"
// synopsys translate_on
`include "can_defines.v"
module can_acf
(
clk,
rst,
id,
/* Mode register */
reset_mode,
acceptance_filter_mode,
extended_mode,
acceptance_code_0,
acceptance_code_1,
acceptance_code_2,
acceptance_code_3,
acceptance_mask_0,
acceptance_mask_1,
acceptance_mask_2,
acceptance_mask_3,
go_rx_crc_lim,
go_rx_inter,
go_error_frame,
data0,
data1,
rtr1,
rtr2,
ide,
no_byte0,
no_byte1,
id_ok
);
parameter Tp = 1;
input clk;
input rst;
input [28:0] id;
input reset_mode;
input acceptance_filter_mode;
input extended_mode;
input [7:0] acceptance_code_0;
input [7:0] acceptance_code_1;
input [7:0] acceptance_code_2;
input [7:0] acceptance_code_3;
input [7:0] acceptance_mask_0;
input [7:0] acceptance_mask_1;
input [7:0] acceptance_mask_2;
input [7:0] acceptance_mask_3;
input go_rx_crc_lim;
input go_rx_inter;
input go_error_frame;
input [7:0] data0;
input [7:0] data1;
input rtr1;
input rtr2;
input ide;
input no_byte0;
input no_byte1;
output id_ok;
reg id_ok;
wire match;
wire match_sf_std;
wire match_sf_ext;
wire match_df_std;
wire match_df_ext;
// Working in basic mode. ID match for standard format (11-bit ID).
assign match = ( (id[3] == acceptance_code_0[0] | acceptance_mask_0[0] ) &
(id[4] == acceptance_code_0[1] | acceptance_mask_0[1] ) &
(id[5] == acceptance_code_0[2] | acceptance_mask_0[2] ) &
(id[6] == acceptance_code_0[3] | acceptance_mask_0[3] ) &
(id[7] == acceptance_code_0[4] | acceptance_mask_0[4] ) &
(id[8] == acceptance_code_0[5] | acceptance_mask_0[5] ) &
(id[9] == acceptance_code_0[6] | acceptance_mask_0[6] ) &
(id[10] == acceptance_code_0[7] | acceptance_mask_0[7] )
);
// Working in extended mode. ID match for standard format (11-bit ID). Using single filter.
assign match_sf_std = ( (id[3] == acceptance_code_0[0] | acceptance_mask_0[0] ) &
(id[4] == acceptance_code_0[1] | acceptance_mask_0[1] ) &
(id[5] == acceptance_code_0[2] | acceptance_mask_0[2] ) &
(id[6] == acceptance_code_0[3] | acceptance_mask_0[3] ) &
(id[7] == acceptance_code_0[4] | acceptance_mask_0[4] ) &
(id[8] == acceptance_code_0[5] | acceptance_mask_0[5] ) &
(id[9] == acceptance_code_0[6] | acceptance_mask_0[6] ) &
(id[10] == acceptance_code_0[7] | acceptance_mask_0[7] ) &
(rtr1 == acceptance_code_1[4] | acceptance_mask_1[4] ) &
(id[0] == acceptance_code_1[5] | acceptance_mask_1[5] ) &
(id[1] == acceptance_code_1[6] | acceptance_mask_1[6] ) &
(id[2] == acceptance_code_1[7] | acceptance_mask_1[7] ) &
(data0[0] == acceptance_code_2[0] | acceptance_mask_2[0] | no_byte0) &
(data0[1] == acceptance_code_2[1] | acceptance_mask_2[1] | no_byte0) &
(data0[2] == acceptance_code_2[2] | acceptance_mask_2[2] | no_byte0) &
(data0[3] == acceptance_code_2[3] | acceptance_mask_2[3] | no_byte0) &
(data0[4] == acceptance_code_2[4] | acceptance_mask_2[4] | no_byte0) &
(data0[5] == acceptance_code_2[5] | acceptance_mask_2[5] | no_byte0) &
(data0[6] == acceptance_code_2[6] | acceptance_mask_2[6] | no_byte0) &
(data0[7] == acceptance_code_2[7] | acceptance_mask_2[7] | no_byte0) &
(data1[0] == acceptance_code_3[0] | acceptance_mask_3[0] | no_byte1) &
(data1[1] == acceptance_code_3[1] | acceptance_mask_3[1] | no_byte1) &
(data1[2] == acceptance_code_3[2] | acceptance_mask_3[2] | no_byte1) &
(data1[3] == acceptance_code_3[3] | acceptance_mask_3[3] | no_byte1) &
(data1[4] == acceptance_code_3[4] | acceptance_mask_3[4] | no_byte1) &
(data1[5] == acceptance_code_3[5] | acceptance_mask_3[5] | no_byte1) &
(data1[6] == acceptance_code_3[6] | acceptance_mask_3[6] | no_byte1) &
(data1[7] == acceptance_code_3[7] | acceptance_mask_3[7] | no_byte1)
);
// Working in extended mode. ID match for extended format (29-bit ID). Using single filter.
assign match_sf_ext = ( (id[21] == acceptance_code_0[0] | acceptance_mask_0[0] ) &
(id[22] == acceptance_code_0[1] | acceptance_mask_0[1] ) &
(id[23] == acceptance_code_0[2] | acceptance_mask_0[2] ) &
(id[24] == acceptance_code_0[3] | acceptance_mask_0[3] ) &
(id[25] == acceptance_code_0[4] | acceptance_mask_0[4] ) &
(id[26] == acceptance_code_0[5] | acceptance_mask_0[5] ) &
(id[27] == acceptance_code_0[6] | acceptance_mask_0[6] ) &
(id[28] == acceptance_code_0[7] | acceptance_mask_0[7] ) &
(id[13] == acceptance_code_1[0] | acceptance_mask_1[0] ) &
(id[14] == acceptance_code_1[1] | acceptance_mask_1[1] ) &
(id[15] == acceptance_code_1[2] | acceptance_mask_1[2] ) &
(id[16] == acceptance_code_1[3] | acceptance_mask_1[3] ) &
(id[17] == acceptance_code_1[4] | acceptance_mask_1[4] ) &
(id[18] == acceptance_code_1[5] | acceptance_mask_1[5] ) &
(id[19] == acceptance_code_1[6] | acceptance_mask_1[6] ) &
(id[20] == acceptance_code_1[7] | acceptance_mask_1[7] ) &
(id[5] == acceptance_code_2[0] | acceptance_mask_2[0] ) &
(id[6] == acceptance_code_2[1] | acceptance_mask_2[1] ) &
(id[7] == acceptance_code_2[2] | acceptance_mask_2[2] ) &
(id[8] == acceptance_code_2[3] | acceptance_mask_2[3] ) &
(id[9] == acceptance_code_2[4] | acceptance_mask_2[4] ) &
(id[10] == acceptance_code_2[5] | acceptance_mask_2[5] ) &
(id[11] == acceptance_code_2[6] | acceptance_mask_2[6] ) &
(id[12] == acceptance_code_2[7] | acceptance_mask_2[7] ) &
(rtr2 == acceptance_code_3[2] | acceptance_mask_3[2] ) &
(id[0] == acceptance_code_3[3] | acceptance_mask_3[3] ) &
(id[1] == acceptance_code_3[4] | acceptance_mask_3[4] ) &
(id[2] == acceptance_code_3[5] | acceptance_mask_3[5] ) &
(id[3] == acceptance_code_3[6] | acceptance_mask_3[6] ) &
(id[4] == acceptance_code_3[7] | acceptance_mask_3[7] )
);
// Working in extended mode. ID match for standard format (11-bit ID). Using double filter.
assign match_df_std = (((id[3] == acceptance_code_0[0] | acceptance_mask_0[0] ) &
(id[4] == acceptance_code_0[1] | acceptance_mask_0[1] ) &
(id[5] == acceptance_code_0[2] | acceptance_mask_0[2] ) &
(id[6] == acceptance_code_0[3] | acceptance_mask_0[3] ) &
(id[7] == acceptance_code_0[4] | acceptance_mask_0[4] ) &
(id[8] == acceptance_code_0[5] | acceptance_mask_0[5] ) &
(id[9] == acceptance_code_0[6] | acceptance_mask_0[6] ) &
(id[10] == acceptance_code_0[7] | acceptance_mask_0[7] ) &
(rtr1 == acceptance_code_1[4] | acceptance_mask_1[4] ) &
(id[0] == acceptance_code_1[5] | acceptance_mask_1[5] ) &
(id[1] == acceptance_code_1[6] | acceptance_mask_1[6] ) &
(id[2] == acceptance_code_1[7] | acceptance_mask_1[7] ) &
(data0[0] == acceptance_code_3[0] | acceptance_mask_3[0] | no_byte0) &
(data0[1] == acceptance_code_3[1] | acceptance_mask_3[1] | no_byte0) &
(data0[2] == acceptance_code_3[2] | acceptance_mask_3[2] | no_byte0) &
(data0[3] == acceptance_code_3[3] | acceptance_mask_3[3] | no_byte0) &
(data0[4] == acceptance_code_1[0] | acceptance_mask_1[0] | no_byte0) &
(data0[5] == acceptance_code_1[1] | acceptance_mask_1[1] | no_byte0) &
(data0[6] == acceptance_code_1[2] | acceptance_mask_1[2] | no_byte0) &
(data0[7] == acceptance_code_1[3] | acceptance_mask_1[3] | no_byte0) )
|
((id[3] == acceptance_code_2[0] | acceptance_mask_2[0] ) &
(id[4] == acceptance_code_2[1] | acceptance_mask_2[1] ) &
(id[5] == acceptance_code_2[2] | acceptance_mask_2[2] ) &
(id[6] == acceptance_code_2[3] | acceptance_mask_2[3] ) &
(id[7] == acceptance_code_2[4] | acceptance_mask_2[4] ) &
(id[8] == acceptance_code_2[5] | acceptance_mask_2[5] ) &
(id[9] == acceptance_code_2[6] | acceptance_mask_2[6] ) &
(id[10] == acceptance_code_2[7] | acceptance_mask_2[7] ) &
(rtr1 == acceptance_code_3[4] | acceptance_mask_3[4] ) &
(id[0] == acceptance_code_3[5] | acceptance_mask_3[5] ) &
(id[1] == acceptance_code_3[6] | acceptance_mask_3[6] ) &
(id[2] == acceptance_code_3[7] | acceptance_mask_3[7] ) )
);
// Working in extended mode. ID match for extended format (29-bit ID). Using double filter.
assign match_df_ext = (((id[21] == acceptance_code_0[0] | acceptance_mask_0[0] ) &
(id[22] == acceptance_code_0[1] | acceptance_mask_0[1] ) &
(id[23] == acceptance_code_0[2] | acceptance_mask_0[2] ) &
(id[24] == acceptance_code_0[3] | acceptance_mask_0[3] ) &
(id[25] == acceptance_code_0[4] | acceptance_mask_0[4] ) &
(id[26] == acceptance_code_0[5] | acceptance_mask_0[5] ) &
(id[27] == acceptance_code_0[6] | acceptance_mask_0[6] ) &
(id[28] == acceptance_code_0[7] | acceptance_mask_0[7] ) &
(id[13] == acceptance_code_1[0] | acceptance_mask_1[0] ) &
(id[14] == acceptance_code_1[1] | acceptance_mask_1[1] ) &
(id[15] == acceptance_code_1[2] | acceptance_mask_1[2] ) &
(id[16] == acceptance_code_1[3] | acceptance_mask_1[3] ) &
(id[17] == acceptance_code_1[4] | acceptance_mask_1[4] ) &
(id[18] == acceptance_code_1[5] | acceptance_mask_1[5] ) &
(id[19] == acceptance_code_1[6] | acceptance_mask_1[6] ) &
(id[20] == acceptance_code_1[7] | acceptance_mask_1[7] ) )
|
((id[21] == acceptance_code_2[0] | acceptance_mask_2[0] ) &
(id[22] == acceptance_code_2[1] | acceptance_mask_2[1] ) &
(id[23] == acceptance_code_2[2] | acceptance_mask_2[2] ) &
(id[24] == acceptance_code_2[3] | acceptance_mask_2[3] ) &
(id[25] == acceptance_code_2[4] | acceptance_mask_2[4] ) &
(id[26] == acceptance_code_2[5] | acceptance_mask_2[5] ) &
(id[27] == acceptance_code_2[6] | acceptance_mask_2[6] ) &
(id[28] == acceptance_code_2[7] | acceptance_mask_2[7] ) &
(id[13] == acceptance_code_3[0] | acceptance_mask_3[0] ) &
(id[14] == acceptance_code_3[1] | acceptance_mask_3[1] ) &
(id[15] == acceptance_code_3[2] | acceptance_mask_3[2] ) &
(id[16] == acceptance_code_3[3] | acceptance_mask_3[3] ) &
(id[17] == acceptance_code_3[4] | acceptance_mask_3[4] ) &
(id[18] == acceptance_code_3[5] | acceptance_mask_3[5] ) &
(id[19] == acceptance_code_3[6] | acceptance_mask_3[6] ) &
(id[20] == acceptance_code_3[7] | acceptance_mask_3[7] ) )
);
// ID ok signal generation
always @ (posedge clk or posedge rst)
begin
if (rst)
id_ok <= 1'b0;
else if (go_rx_crc_lim) // sample_point is already included in go_rx_crc_lim
begin
if (extended_mode)
begin
if (~acceptance_filter_mode) // dual filter
begin
if (ide) // extended frame message
id_ok <=#Tp match_df_ext;
else // standard frame message
id_ok <=#Tp match_df_std;
end
else // single filter
begin
if (ide) // extended frame message
id_ok <=#Tp match_sf_ext;
else // standard frame message
id_ok <=#Tp match_sf_std;
end
end
else
id_ok <=#Tp match;
end
else if (reset_mode | go_rx_inter | go_error_frame) // sample_point is already included in go_rx_inter
id_ok <=#Tp 1'b0;
end
endmodule

1961
soc/peripheral/can_bsp.v Normal file

File diff suppressed because it is too large Load Diff

381
soc/peripheral/can_btl.v Normal file
View File

@@ -0,0 +1,381 @@
//////////////////////////////////////////////////////////////////////
//// ////
//// can_btl.v ////
//// ////
//// ////
//// This file is part of the CAN Protocol Controller ////
//// http://www.opencores.org/projects/can/ ////
//// ////
//// ////
//// Author(s): ////
//// Igor Mohor ////
//// igorm@opencores.org ////
//// ////
//// ////
//// All additional information is available in the README.txt ////
//// file. ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2002, 2003, 2004 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//// The CAN protocol is developed by Robert Bosch GmbH and ////
//// protected by patents. Anybody who wants to implement this ////
//// CAN IP core on silicon has to obtain a CAN protocol license ////
//// from Bosch. ////
//// ////
//////////////////////////////////////////////////////////////////////
// synopsys translate_off
// `include "timescale.v"
// synopsys translate_on
`include "can_defines.v"
module can_btl
(
clk,
rst,
rx,
tx,
/* Bus Timing 0 register */
baud_r_presc,
sync_jump_width,
/* Bus Timing 1 register */
time_segment1,
time_segment2,
triple_sampling,
/* Output signals from this module */
sample_point,
sampled_bit,
sampled_bit_q,
tx_point,
hard_sync,
/* Output from can_bsp module */
rx_idle,
rx_inter,
transmitting,
transmitter,
go_rx_inter,
tx_next,
go_overload_frame,
go_error_frame,
go_tx,
send_ack,
node_error_passive
);
parameter Tp = 1;
input clk;
input rst;
input rx;
input tx;
/* Bus Timing 0 register */
input [5:0] baud_r_presc;
input [1:0] sync_jump_width;
/* Bus Timing 1 register */
input [3:0] time_segment1;
input [2:0] time_segment2;
input triple_sampling;
/* Output from can_bsp module */
input rx_idle;
input rx_inter;
input transmitting;
input transmitter;
input go_rx_inter;
input tx_next;
input go_overload_frame;
input go_error_frame;
input go_tx;
input send_ack;
input node_error_passive;
/* Output signals from this module */
output sample_point;
output sampled_bit;
output sampled_bit_q;
output tx_point;
output hard_sync;
reg [6:0] clk_cnt;
reg clk_en;
reg clk_en_q;
reg sync_blocked;
reg hard_sync_blocked;
reg sampled_bit;
reg sampled_bit_q;
reg [4:0] quant_cnt;
reg [3:0] delay;
reg sync;
reg seg1;
reg seg2;
reg resync_latched;
reg sample_point;
reg [1:0] sample;
reg tx_point;
reg tx_next_sp;
wire go_sync;
wire go_seg1;
wire go_seg2;
wire [7:0] preset_cnt;
wire sync_window;
wire resync;
assign preset_cnt = (baud_r_presc + 1'b1)<<1; // (BRP+1)*2
assign hard_sync = (rx_idle | rx_inter) & (~rx) & sampled_bit & (~hard_sync_blocked); // Hard synchronization
assign resync = (~rx_idle) & (~rx_inter) & (~rx) & sampled_bit & (~sync_blocked); // Re-synchronization
/* Generating general enable signal that defines baud rate. */
always @ (posedge clk or posedge rst)
begin
if (rst)
clk_cnt <= 7'h0;
else if (clk_cnt >= (preset_cnt-1'b1))
clk_cnt <=#Tp 7'h0;
else
clk_cnt <=#Tp clk_cnt + 1'b1;
end
always @ (posedge clk or posedge rst)
begin
if (rst)
clk_en <= 1'b0;
else if ({1'b0, clk_cnt} == (preset_cnt-1'b1))
clk_en <=#Tp 1'b1;
else
clk_en <=#Tp 1'b0;
end
always @ (posedge clk or posedge rst)
begin
if (rst)
clk_en_q <= 1'b0;
else
clk_en_q <=#Tp clk_en;
end
/* Changing states */
assign go_sync = clk_en_q & seg2 & (quant_cnt[2:0] == time_segment2) & (~hard_sync) & (~resync);
assign go_seg1 = clk_en_q & (sync | hard_sync | (resync & seg2 & sync_window) | (resync_latched & sync_window));
assign go_seg2 = clk_en_q & (seg1 & (~hard_sync) & (quant_cnt == (time_segment1 + delay)));
always @ (posedge clk or posedge rst)
begin
if (rst)
tx_point <= 1'b0;
else
tx_point <=#Tp ~tx_point & seg2 & ( clk_en & (quant_cnt[2:0] == time_segment2)
| (clk_en | clk_en_q) & (resync | hard_sync)
); // When transmitter we should transmit as soon as possible.
end
/* When early edge is detected outside of the SJW field, synchronization request is latched and performed when
SJW is reached */
always @ (posedge clk or posedge rst)
begin
if (rst)
resync_latched <= 1'b0;
else if (resync & seg2 & (~sync_window))
resync_latched <=#Tp 1'b1;
else if (go_seg1)
resync_latched <= 1'b0;
end
/* Synchronization stage/segment */
always @ (posedge clk or posedge rst)
begin
if (rst)
sync <= 1'b0;
else if (clk_en_q)
sync <=#Tp go_sync;
end
/* Seg1 stage/segment (together with propagation segment which is 1 quant long) */
always @ (posedge clk or posedge rst)
begin
if (rst)
seg1 <= 1'b1;
else if (go_seg1)
seg1 <=#Tp 1'b1;
else if (go_seg2)
seg1 <=#Tp 1'b0;
end
/* Seg2 stage/segment */
always @ (posedge clk or posedge rst)
begin
if (rst)
seg2 <= 1'b0;
else if (go_seg2)
seg2 <=#Tp 1'b1;
else if (go_sync | go_seg1)
seg2 <=#Tp 1'b0;
end
/* Quant counter */
always @ (posedge clk or posedge rst)
begin
if (rst)
quant_cnt <= 5'h0;
else if (go_sync | go_seg1 | go_seg2)
quant_cnt <=#Tp 5'h0;
else if (clk_en_q)
quant_cnt <=#Tp quant_cnt + 1'b1;
end
/* When late edge is detected (in seg1 stage), stage seg1 is prolonged. */
always @ (posedge clk or posedge rst)
begin
if (rst)
delay <= 4'h0;
else if (resync & seg1 & (~transmitting | transmitting & (tx_next_sp | (tx & (~rx))))) // when transmitting 0 with positive error delay is set to 0
delay <=#Tp (quant_cnt > {3'h0, sync_jump_width})? ({2'h0, sync_jump_width} + 1'b1) : (quant_cnt + 1'b1);
else if (go_sync | go_seg1)
delay <=#Tp 4'h0;
end
// If early edge appears within this window (in seg2 stage), phase error is fully compensated
assign sync_window = ((time_segment2 - quant_cnt[2:0]) < ( sync_jump_width + 1'b1));
// Sampling data (memorizing two samples all the time).
always @ (posedge clk or posedge rst)
begin
if (rst)
sample <= 2'b11;
else if (clk_en_q)
sample <= {sample[0], rx};
end
// When enabled, tripple sampling is done here.
always @ (posedge clk or posedge rst)
begin
if (rst)
begin
sampled_bit <= 1'b1;
sampled_bit_q <= 1'b1;
sample_point <= 1'b0;
end
else if (go_error_frame)
begin
sampled_bit_q <=#Tp sampled_bit;
sample_point <=#Tp 1'b0;
end
else if (clk_en_q & (~hard_sync))
begin
if (seg1 & (quant_cnt == (time_segment1 + delay)))
begin
sample_point <=#Tp 1'b1;
sampled_bit_q <=#Tp sampled_bit;
if (triple_sampling)
sampled_bit <=#Tp (sample[0] & sample[1]) | ( sample[0] & rx) | (sample[1] & rx);
else
sampled_bit <=#Tp rx;
end
end
else
sample_point <=#Tp 1'b0;
end
// tx_next_sp shows next value that will be driven on the TX. When driving 1 and receiving 0 we
// need to synchronize (even when we are a transmitter)
always @ (posedge clk or posedge rst)
begin
if (rst)
tx_next_sp <= 1'b0;
else if (go_overload_frame | (go_error_frame & (~node_error_passive)) | go_tx | send_ack)
tx_next_sp <=#Tp 1'b0;
else if (go_error_frame & node_error_passive)
tx_next_sp <=#Tp 1'b1;
else if (sample_point)
tx_next_sp <=#Tp tx_next;
end
/* Blocking synchronization (can occur only once in a bit time) */
always @ (posedge clk or posedge rst)
begin
if (rst)
sync_blocked <=#Tp 1'b1;
else if (clk_en_q)
begin
if (resync)
sync_blocked <=#Tp 1'b1;
else if (go_seg2)
sync_blocked <=#Tp 1'b0;
end
end
/* Blocking hard synchronization when occurs once or when we are transmitting a msg */
always @ (posedge clk or posedge rst)
begin
if (rst)
hard_sync_blocked <=#Tp 1'b0;
else if (hard_sync & clk_en_q | (transmitting & transmitter | go_tx) & tx_point & (~tx_next))
hard_sync_blocked <=#Tp 1'b1;
else if (go_rx_inter | (rx_idle | rx_inter) & sample_point & sampled_bit) // When a glitch performed synchronization
hard_sync_blocked <=#Tp 1'b0;
end
endmodule

89
soc/peripheral/can_crc.v Normal file
View File

@@ -0,0 +1,89 @@
//////////////////////////////////////////////////////////////////////
//// ////
//// can_crc.v ////
//// ////
//// ////
//// This file is part of the CAN Protocol Controller ////
//// http://www.opencores.org/projects/can/ ////
//// ////
//// ////
//// Author(s): ////
//// Igor Mohor ////
//// igorm@opencores.org ////
//// ////
//// ////
//// All additional information is available in the README.txt ////
//// file. ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2002, 2003, 2004 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//// The CAN protocol is developed by Robert Bosch GmbH and ////
//// protected by patents. Anybody who wants to implement this ////
//// CAN IP core on silicon has to obtain a CAN protocol license ////
//// from Bosch. ////
//// ////
//////////////////////////////////////////////////////////////////////
// synopsys translate_off
// `include "timescale.v"
// synopsys translate_on
module can_crc (clk, data, enable, initialize, crc);
parameter Tp = 1;
input clk;
input data;
input enable;
input initialize;
output [14:0] crc;
reg [14:0] crc;
wire crc_next;
wire [14:0] crc_tmp;
assign crc_next = data ^ crc[14];
assign crc_tmp = {crc[13:0], 1'b0};
always @ (posedge clk)
begin
if(initialize)
crc <= #Tp 15'h0;
else if (enable)
begin
if (crc_next)
crc <= #Tp crc_tmp ^ 15'h4599;
else
crc <= #Tp crc_tmp;
end
end
endmodule

72
soc/peripheral/can_defines.v Executable file
View File

@@ -0,0 +1,72 @@
//////////////////////////////////////////////////////////////////////
//// ////
//// can_defines.v ////
//// ////
//// ////
//// This file is part of the CAN Protocol Controller ////
//// http://www.opencores.org/projects/can/ ////
//// ////
//// ////
//// Author(s): ////
//// Igor Mohor ////
//// igorm@opencores.org ////
//// ////
//// ////
//// All additional information is available in the README.txt ////
//// file. ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2002, 2003, 2004 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//// The CAN protocol is developed by Robert Bosch GmbH and ////
//// protected by patents. Anybody who wants to implement this ////
//// CAN IP core on silicon has to obtain a CAN protocol license ////
//// from Bosch. ////
//// ////
//////////////////////////////////////////////////////////////////////
// Uncomment following line if you want to use WISHBONE interface. Otherwise
// 8051 interface is used.
`define CAN_WISHBONE_IF
// Uncomment following line if you want to use CAN in Actel APA devices (embedded memory used)
// `define ACTEL_APA_RAM
// Uncomment following line if you want to use CAN in Altera devices (embedded memory used)
// `define ALTERA_RAM
// Uncomment following line if you want to use CAN in Xilinx devices (embedded memory used)
// `define XILINX_RAM
// Uncomment the line for the ram used in ASIC implementation
// `define VIRTUALSILICON_RAM
// `define ARTISAN_RAM
// Uncomment the following line when RAM BIST is needed (ASIC implementation)
//`define CAN_BIST // Bist (for ASIC implementation)
/* width of MBIST control bus */
//`define CAN_MBIST_CTRL_WIDTH 3

622
soc/peripheral/can_fifo.v Normal file
View File

@@ -0,0 +1,622 @@
//////////////////////////////////////////////////////////////////////
//// ////
//// can_fifo.v ////
//// ////
//// ////
//// This file is part of the CAN Protocol Controller ////
//// http://www.opencores.org/projects/can/ ////
//// ////
//// ////
//// Author(s): ////
//// Igor Mohor ////
//// igorm@opencores.org ////
//// ////
//// ////
//// All additional information is available in the README.txt ////
//// file. ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2002, 2003, 2004 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//// The CAN protocol is developed by Robert Bosch GmbH and ////
//// protected by patents. Anybody who wants to implement this ////
//// CAN IP core on silicon has to obtain a CAN protocol license ////
//// from Bosch. ////
//// ////
//////////////////////////////////////////////////////////////////////
// synopsys translate_off
// `include "timescale.v"
// synopsys translate_on
`include "can_defines.v"
module can_fifo
(
clk,
rst,
wr,
data_in,
addr,
data_out,
fifo_selected,
reset_mode,
release_buffer,
extended_mode,
overrun,
info_empty,
info_cnt
`ifdef CAN_BIST
,
mbist_si_i,
mbist_so_o,
mbist_ctrl_i
`endif
);
parameter Tp = 1;
input clk;
input rst;
input wr;
input [7:0] data_in;
input [5:0] addr;
input reset_mode;
input release_buffer;
input extended_mode;
input fifo_selected;
output [7:0] data_out;
output overrun;
output info_empty;
output [6:0] info_cnt;
`ifdef CAN_BIST
input mbist_si_i;
output mbist_so_o;
input [`CAN_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control
wire mbist_s_0;
`endif
`ifdef ALTERA_RAM
`else
`ifdef ACTEL_APA_RAM
`else
`ifdef XILINX_RAM
`else
`ifdef ARTISAN_RAM
reg overrun_info[0:63];
`else
`ifdef VIRTUALSILICON_RAM
reg overrun_info[0:63];
`else
reg [7:0] fifo [0:63];
reg [3:0] length_fifo[0:63];
reg overrun_info[0:63];
`endif
`endif
`endif
`endif
`endif
reg [5:0] rd_pointer;
reg [5:0] wr_pointer;
reg [5:0] read_address;
reg [5:0] wr_info_pointer;
reg [5:0] rd_info_pointer;
reg wr_q;
reg [3:0] len_cnt;
reg [6:0] fifo_cnt;
reg [6:0] info_cnt;
reg latch_overrun;
reg initialize_memories;
wire [3:0] length_info;
wire write_length_info;
wire fifo_empty;
wire fifo_full;
wire info_full;
assign write_length_info = (~wr) & wr_q;
// Delayed write signal
always @ (posedge clk or posedge rst)
begin
if (rst)
wr_q <=#Tp 1'b0;
else if (reset_mode)
wr_q <=#Tp 1'b0;
else
wr_q <=#Tp wr;
end
// length counter
always @ (posedge clk or posedge rst)
begin
if (rst)
len_cnt <= 4'h0;
else if (reset_mode | write_length_info)
len_cnt <=#Tp 4'h0;
else if (wr & (~fifo_full))
len_cnt <=#Tp len_cnt + 1'b1;
end
// wr_info_pointer
always @ (posedge clk or posedge rst)
begin
if (rst)
wr_info_pointer <= 6'h0;
else if (write_length_info & (~info_full) | initialize_memories)
wr_info_pointer <=#Tp wr_info_pointer + 1'b1;
else if (reset_mode)
wr_info_pointer <=#Tp rd_info_pointer;
end
// rd_info_pointer
always @ (posedge clk or posedge rst)
begin
if (rst)
rd_info_pointer <= 6'h0;
else if (release_buffer & (~info_full))
rd_info_pointer <=#Tp rd_info_pointer + 1'b1;
end
// rd_pointer
always @ (posedge clk or posedge rst)
begin
if (rst)
rd_pointer <= 5'h0;
else if (release_buffer & (~fifo_empty))
rd_pointer <=#Tp rd_pointer + {2'h0, length_info};
end
// wr_pointer
always @ (posedge clk or posedge rst)
begin
if (rst)
wr_pointer <= 5'h0;
else if (reset_mode)
wr_pointer <=#Tp rd_pointer;
else if (wr & (~fifo_full))
wr_pointer <=#Tp wr_pointer + 1'b1;
end
// latch_overrun
always @ (posedge clk or posedge rst)
begin
if (rst)
latch_overrun <= 1'b0;
else if (reset_mode | write_length_info)
latch_overrun <=#Tp 1'b0;
else if (wr & fifo_full)
latch_overrun <=#Tp 1'b1;
end
// Counting data in fifo
always @ (posedge clk or posedge rst)
begin
if (rst)
fifo_cnt <= 7'h0;
else if (reset_mode)
fifo_cnt <=#Tp 7'h0;
else if (wr & (~release_buffer) & (~fifo_full))
fifo_cnt <=#Tp fifo_cnt + 1'b1;
else if ((~wr) & release_buffer & (~fifo_empty))
fifo_cnt <=#Tp fifo_cnt - {3'h0, length_info};
else if (wr & release_buffer & (~fifo_full) & (~fifo_empty))
fifo_cnt <=#Tp fifo_cnt - {3'h0, length_info} + 1'b1;
end
assign fifo_full = fifo_cnt == 7'd64;
assign fifo_empty = fifo_cnt == 7'd0;
// Counting data in length_fifo and overrun_info fifo
always @ (posedge clk or posedge rst)
begin
if (rst)
info_cnt <=#Tp 7'h0;
else if (reset_mode)
info_cnt <=#Tp 7'h0;
else if (write_length_info ^ release_buffer)
begin
if (release_buffer & (~info_empty))
info_cnt <=#Tp info_cnt - 1'b1;
else if (write_length_info & (~info_full))
info_cnt <=#Tp info_cnt + 1'b1;
end
end
assign info_full = info_cnt == 7'd64;
assign info_empty = info_cnt == 7'd0;
// Selecting which address will be used for reading data from rx fifo
always @ (extended_mode or rd_pointer or addr)
begin
if (extended_mode) // extended mode
read_address = rd_pointer + (addr - 6'd16);
else // normal mode
read_address = rd_pointer + (addr - 6'd20);
end
always @ (posedge clk or posedge rst)
begin
if (rst)
initialize_memories <= 1'b1;
else if (&wr_info_pointer)
initialize_memories <=#Tp 1'b0;
end
`ifdef ALTERA_RAM
// altera_ram_64x8_sync fifo
lpm_ram_dp fifo
(
.q (data_out),
.rdclock (clk),
.wrclock (clk),
.data (data_in),
.wren (wr & (~fifo_full)),
.rden (fifo_selected),
.wraddress (wr_pointer),
.rdaddress (read_address)
);
defparam fifo.lpm_width = 8;
defparam fifo.lpm_widthad = 6;
defparam fifo.lpm_numwords = 64;
// altera_ram_64x4_sync info_fifo
lpm_ram_dp info_fifo
(
.q (length_info),
.rdclock (clk),
.wrclock (clk),
.data (len_cnt & {4{~initialize_memories}}),
.wren (write_length_info & (~info_full) | initialize_memories),
.wraddress (wr_info_pointer),
.rdaddress (rd_info_pointer)
);
defparam info_fifo.lpm_width = 4;
defparam info_fifo.lpm_widthad = 6;
defparam info_fifo.lpm_numwords = 64;
// altera_ram_64x1_sync overrun_fifo
lpm_ram_dp overrun_fifo
(
.q (overrun),
.rdclock (clk),
.wrclock (clk),
.data ((latch_overrun | (wr & fifo_full)) & (~initialize_memories)),
.wren (write_length_info & (~info_full) | initialize_memories),
.wraddress (wr_info_pointer),
.rdaddress (rd_info_pointer)
);
defparam overrun_fifo.lpm_width = 1;
defparam overrun_fifo.lpm_widthad = 6;
defparam overrun_fifo.lpm_numwords = 64;
`else
`ifdef ACTEL_APA_RAM
actel_ram_64x8_sync fifo
(
.DO (data_out),
.RCLOCK (clk),
.WCLOCK (clk),
.DI (data_in),
.PO (), // parity not used
.WRB (~(wr & (~fifo_full))),
.RDB (~fifo_selected),
.WADDR (wr_pointer),
.RADDR (read_address)
);
actel_ram_64x4_sync info_fifo
(
.DO (length_info),
.RCLOCK (clk),
.WCLOCK (clk),
.DI (len_cnt & {4{~initialize_memories}}),
.PO (), // parity not used
.WRB (~(write_length_info & (~info_full) | initialize_memories)),
.RDB (1'b0), // always enabled
.WADDR (wr_info_pointer),
.RADDR (rd_info_pointer)
);
actel_ram_64x1_sync overrun_fifo
(
.DO (overrun),
.RCLOCK (clk),
.WCLOCK (clk),
.DI ((latch_overrun | (wr & fifo_full)) & (~initialize_memories)),
.PO (), // parity not used
.WRB (~(write_length_info & (~info_full) | initialize_memories)),
.RDB (1'b0), // always enabled
.WADDR (wr_info_pointer),
.RADDR (rd_info_pointer)
);
`else
`ifdef XILINX_RAM
RAMB4_S8_S8 fifo
(
.DOA(),
.DOB(data_out),
.ADDRA({3'h0, wr_pointer}),
.CLKA(clk),
.DIA(data_in),
.ENA(1'b1),
.RSTA(1'b0),
.WEA(wr & (~fifo_full)),
.ADDRB({3'h0, read_address}),
.CLKB(clk),
.DIB(8'h0),
.ENB(1'b1),
.RSTB(1'b0),
.WEB(1'b0)
);
RAMB4_S4_S4 info_fifo
(
.DOA(),
.DOB(length_info),
.ADDRA({4'h0, wr_info_pointer}),
.CLKA(clk),
.DIA(len_cnt & {4{~initialize_memories}}),
.ENA(1'b1),
.RSTA(1'b0),
.WEA(write_length_info & (~info_full) | initialize_memories),
.ADDRB({4'h0, rd_info_pointer}),
.CLKB(clk),
.DIB(4'h0),
.ENB(1'b1),
.RSTB(1'b0),
.WEB(1'b0)
);
RAMB4_S1_S1 overrun_fifo
(
.DOA(),
.DOB(overrun),
.ADDRA({6'h0, wr_info_pointer}),
.CLKA(clk),
.DIA((latch_overrun | (wr & fifo_full)) & (~initialize_memories)),
.ENA(1'b1),
.RSTA(1'b0),
.WEA(write_length_info & (~info_full) | initialize_memories),
.ADDRB({6'h0, rd_info_pointer}),
.CLKB(clk),
.DIB(1'h0),
.ENB(1'b1),
.RSTB(1'b0),
.WEB(1'b0)
);
`else
`ifdef VIRTUALSILICON_RAM
`ifdef CAN_BIST
vs_hdtp_64x8_bist fifo
`else
vs_hdtp_64x8 fifo
`endif
(
.RCK (clk),
.WCK (clk),
.RADR (read_address),
.WADR (wr_pointer),
.DI (data_in),
.DOUT (data_out),
.REN (~fifo_selected),
.WEN (~(wr & (~fifo_full)))
`ifdef CAN_BIST
,
// debug chain signals
.mbist_si_i (mbist_si_i),
.mbist_so_o (mbist_s_0),
.mbist_ctrl_i (mbist_ctrl_i)
`endif
);
`ifdef CAN_BIST
vs_hdtp_64x4_bist info_fifo
`else
vs_hdtp_64x4 info_fifo
`endif
(
.RCK (clk),
.WCK (clk),
.RADR (rd_info_pointer),
.WADR (wr_info_pointer),
.DI (len_cnt & {4{~initialize_memories}}),
.DOUT (length_info),
.REN (1'b0),
.WEN (~(write_length_info & (~info_full) | initialize_memories))
`ifdef CAN_BIST
,
// debug chain signals
.mbist_si_i (mbist_s_0),
.mbist_so_o (mbist_so_o),
.mbist_ctrl_i (mbist_ctrl_i)
`endif
);
// overrun_info
always @ (posedge clk)
begin
if (write_length_info & (~info_full) | initialize_memories)
overrun_info[wr_info_pointer] <=#Tp (latch_overrun | (wr & fifo_full)) & (~initialize_memories);
end
// reading overrun
assign overrun = overrun_info[rd_info_pointer];
`else
`ifdef ARTISAN_RAM
`ifdef CAN_BIST
art_hstp_64x8_bist fifo
(
.CLKR (clk),
.CLKW (clk),
.AR (read_address),
.AW (wr_pointer),
.D (data_in),
.Q (data_out),
.REN (~fifo_selected),
.WEN (~(wr & (~fifo_full))),
.mbist_si_i (mbist_si_i),
.mbist_so_o (mbist_s_0),
.mbist_ctrl_i (mbist_ctrl_i)
);
art_hstp_64x4_bist info_fifo
(
.CLKR (clk),
.CLKW (clk),
.AR (rd_info_pointer),
.AW (wr_info_pointer),
.D (len_cnt & {4{~initialize_memories}}),
.Q (length_info),
.REN (1'b0),
.WEN (~(write_length_info & (~info_full) | initialize_memories)),
.mbist_si_i (mbist_s_0),
.mbist_so_o (mbist_so_o),
.mbist_ctrl_i (mbist_ctrl_i)
);
`else
art_hsdp_64x8 fifo
(
.CENA (1'b0),
.CENB (1'b0),
.CLKA (clk),
.CLKB (clk),
.AA (read_address),
.AB (wr_pointer),
.DA (8'h00),
.DB (data_in),
.QA (data_out),
.QB (),
.OENA (~fifo_selected),
.OENB (1'b1),
.WENA (1'b1),
.WENB (~(wr & (~fifo_full)))
);
art_hsdp_64x4 info_fifo
(
.CENA (1'b0),
.CENB (1'b0),
.CLKA (clk),
.CLKB (clk),
.AA (rd_info_pointer),
.AB (wr_info_pointer),
.DA (4'h0),
.DB (len_cnt & {4{~initialize_memories}}),
.QA (length_info),
.QB (),
.OENA (1'b0),
.OENB (1'b1),
.WENA (1'b1),
.WENB (~(write_length_info & (~info_full) | initialize_memories))
);
`endif
// overrun_info
always @ (posedge clk)
begin
if (write_length_info & (~info_full) | initialize_memories)
overrun_info[wr_info_pointer] <=#Tp (latch_overrun | (wr & fifo_full)) & (~initialize_memories);
end
// reading overrun
assign overrun = overrun_info[rd_info_pointer];
`else
// writing data to fifo
always @ (posedge clk)
begin
if (wr & (~fifo_full))
fifo[wr_pointer] <=#Tp data_in;
end
// reading from fifo
assign data_out = fifo[read_address];
// writing length_fifo
always @ (posedge clk)
begin
if (write_length_info & (~info_full) | initialize_memories)
length_fifo[wr_info_pointer] <=#Tp len_cnt & {4{~initialize_memories}};
end
// reading length_fifo
assign length_info = length_fifo[rd_info_pointer];
// overrun_info
always @ (posedge clk)
begin
if (write_length_info & (~info_full) | initialize_memories)
overrun_info[wr_info_pointer] <=#Tp (latch_overrun | (wr & fifo_full)) & (~initialize_memories);
end
// reading overrun
assign overrun = overrun_info[rd_info_pointer];
`endif
`endif
`endif
`endif
`endif
endmodule

69
soc/peripheral/can_ibo.v Normal file
View File

@@ -0,0 +1,69 @@
//////////////////////////////////////////////////////////////////////
//// ////
//// can_ibo.v ////
//// ////
//// ////
//// This file is part of the CAN Protocol Controller ////
//// http://www.opencores.org/projects/can/ ////
//// ////
//// ////
//// Author(s): ////
//// Igor Mohor ////
//// igorm@opencores.org ////
//// ////
//// ////
//// All additional information is available in the README.txt ////
//// file. ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2002, 2003, 2004 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//// The CAN protocol is developed by Robert Bosch GmbH and ////
//// protected by patents. Anybody who wants to implement this ////
//// CAN IP core on silicon has to obtain a CAN protocol license ////
//// from Bosch. ////
//// ////
//////////////////////////////////////////////////////////////////////
// This module only inverts bit order
module can_ibo
(
di,
do
);
input [7:0] di;
output [7:0] do;
assign do[0] = di[7];
assign do[1] = di[6];
assign do[2] = di[5];
assign do[3] = di[4];
assign do[4] = di[3];
assign do[5] = di[2];
assign do[6] = di[1];
assign do[7] = di[0];
endmodule

81
soc/peripheral/can_register.v Executable file
View File

@@ -0,0 +1,81 @@
//////////////////////////////////////////////////////////////////////
//// ////
//// can_register.v ////
//// ////
//// ////
//// This file is part of the CAN Protocol Controller ////
//// http://www.opencores.org/projects/can/ ////
//// ////
//// ////
//// Author(s): ////
//// Igor Mohor ////
//// igorm@opencores.org ////
//// ////
//// ////
//// All additional information is available in the README.txt ////
//// file. ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2002, 2003, 2004 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//// The CAN protocol is developed by Robert Bosch GmbH and ////
//// protected by patents. Anybody who wants to implement this ////
//// CAN IP core on silicon has to obtain a CAN protocol license ////
//// from Bosch. ////
//// ////
//////////////////////////////////////////////////////////////////////
// synopsys translate_off
// `include "timescale.v"
// synopsys translate_on
module can_register
( data_in,
data_out,
we,
clk
);
parameter WIDTH = 8; // default parameter of the register width
input [WIDTH-1:0] data_in;
input we;
input clk;
output [WIDTH-1:0] data_out;
reg [WIDTH-1:0] data_out;
always @ (posedge clk)
begin
if (we) // write
data_out<=#1 data_in;
end
endmodule

View File

@@ -0,0 +1,86 @@
//////////////////////////////////////////////////////////////////////
//// ////
//// can_register_asyn.v ////
//// ////
//// ////
//// This file is part of the CAN Protocol Controller ////
//// http://www.opencores.org/projects/can/ ////
//// ////
//// ////
//// Author(s): ////
//// Igor Mohor ////
//// igorm@opencores.org ////
//// ////
//// ////
//// All additional information is available in the README.txt ////
//// file. ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2002, 2003, 2004 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//// The CAN protocol is developed by Robert Bosch GmbH and ////
//// protected by patents. Anybody who wants to implement this ////
//// CAN IP core on silicon has to obtain a CAN protocol license ////
//// from Bosch. ////
//// ////
//////////////////////////////////////////////////////////////////////
// synopsys translate_off
// `include "timescale.v"
// synopsys translate_on
module can_register_asyn
( data_in,
data_out,
we,
clk,
rst
);
parameter WIDTH = 8; // default parameter of the register width
parameter RESET_VALUE = 0;
input [WIDTH-1:0] data_in;
input we;
input clk;
input rst;
output [WIDTH-1:0] data_out;
reg [WIDTH-1:0] data_out;
always @ (posedge clk or posedge rst)
begin
if (rst) // asynchronous reset
data_out<=#1 RESET_VALUE;
else if (we) // write
data_out<=#1 data_in;
end
endmodule

View File

@@ -0,0 +1,90 @@
//////////////////////////////////////////////////////////////////////
//// ////
//// can_register_asyn_syn.v ////
//// ////
//// ////
//// This file is part of the CAN Protocol Controller ////
//// http://www.opencores.org/projects/can/ ////
//// ////
//// ////
//// Author(s): ////
//// Igor Mohor ////
//// igorm@opencores.org ////
//// ////
//// ////
//// All additional information is available in the README.txt ////
//// file. ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2002, 2003, 2004 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//// The CAN protocol is developed by Robert Bosch GmbH and ////
//// protected by patents. Anybody who wants to implement this ////
//// CAN IP core on silicon has to obtain a CAN protocol license ////
//// from Bosch. ////
//// ////
//////////////////////////////////////////////////////////////////////
// synopsys translate_off
// `include "timescale.v"
// synopsys translate_on
module can_register_asyn_syn
( data_in,
data_out,
we,
clk,
rst,
rst_sync
);
parameter WIDTH = 8; // default parameter of the register width
parameter RESET_VALUE = 0;
input [WIDTH-1:0] data_in;
input we;
input clk;
input rst;
input rst_sync;
output [WIDTH-1:0] data_out;
reg [WIDTH-1:0] data_out;
always @ (posedge clk or posedge rst)
begin
if(rst)
data_out<=#1 RESET_VALUE;
else if (rst_sync) // synchronous reset
data_out<=#1 RESET_VALUE;
else if (we) // write
data_out<=#1 data_in;
end
endmodule

View File

@@ -0,0 +1,86 @@
//////////////////////////////////////////////////////////////////////
//// ////
//// can_register_syn.v ////
//// ////
//// ////
//// This file is part of the CAN Protocol Controller ////
//// http://www.opencores.org/projects/can/ ////
//// ////
//// ////
//// Author(s): ////
//// Igor Mohor ////
//// igorm@opencores.org ////
//// ////
//// ////
//// All additional information is available in the README.txt ////
//// file. ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2002, 2003, 2004 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//// The CAN protocol is developed by Robert Bosch GmbH and ////
//// protected by patents. Anybody who wants to implement this ////
//// CAN IP core on silicon has to obtain a CAN protocol license ////
//// from Bosch. ////
//// ////
//////////////////////////////////////////////////////////////////////
// synopsys translate_off
// `include "timescale.v"
// synopsys translate_on
module can_register_syn
( data_in,
data_out,
we,
clk,
rst_sync
);
parameter WIDTH = 8; // default parameter of the register width
parameter RESET_VALUE = 0;
input [WIDTH-1:0] data_in;
input we;
input clk;
input rst_sync;
output [WIDTH-1:0] data_out;
reg [WIDTH-1:0] data_out;
always @ (posedge clk)
begin
if (rst_sync) // synchronous reset
data_out<=#1 RESET_VALUE;
else if (we) // write
data_out<=#1 data_in;
end
endmodule

1138
soc/peripheral/can_registers.v Executable file

File diff suppressed because it is too large Load Diff

715
soc/peripheral/can_top.v Normal file
View File

@@ -0,0 +1,715 @@
//////////////////////////////////////////////////////////////////////
//// ////
//// can_top.v ////
//// ////
//// ////
//// This file is part of the CAN Protocol Controller ////
//// http://www.opencores.org/projects/can/ ////
//// ////
//// ////
//// Author(s): ////
//// Igor Mohor ////
//// igorm@opencores.org ////
//// ////
//// ////
//// All additional information is available in the README.txt ////
//// file. ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2002, 2003, 2004 Authors ////
//// ////
//// This source file may be used and distributed without ////
//// restriction provided that this copyright statement is not ////
//// removed from the file and that any derivative work contains ////
//// the original copyright notice and the associated disclaimer. ////
//// ////
//// This source file is free software; you can redistribute it ////
//// and/or modify it under the terms of the GNU Lesser General ////
//// Public License as published by the Free Software Foundation; ////
//// either version 2.1 of the License, or (at your option) any ////
//// later version. ////
//// ////
//// This source is distributed in the hope that it will be ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
//// PURPOSE. See the GNU Lesser General Public License for more ////
//// details. ////
//// ////
//// You should have received a copy of the GNU Lesser General ////
//// Public License along with this source; if not, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//// The CAN protocol is developed by Robert Bosch GmbH and ////
//// protected by patents. Anybody who wants to implement this ////
//// CAN IP core on silicon has to obtain a CAN protocol license ////
//// from Bosch. ////
//// ////
//////////////////////////////////////////////////////////////////////
// synopsys translate_off
//`include "timescale.v" //commented this out, see what breaks... -TF
// synopsys translate_on
`include "can_defines.v"
module can_top
(
`ifdef CAN_WISHBONE_IF
wb_clk_i,
wb_rst_i,
wb_dat_i,
wb_dat_o,
wb_cyc_i,
wb_stb_i,
wb_we_i,
wb_adr_i,
wb_ack_o,
`else
rst_i,
ale_i,
rd_i,
wr_i,
port_0_io,
cs_can_i,
`endif
clk_i,
rx_i,
tx_o,
bus_off_on,
irq_on,
clkout_o
// Bist
`ifdef CAN_BIST
,
// debug chain signals
mbist_si_i, // bist scan serial in
mbist_so_o, // bist scan serial out
mbist_ctrl_i // bist chain shift control
`endif
);
parameter Tp = 1;
`ifdef CAN_WISHBONE_IF
input wb_clk_i;
input wb_rst_i;
input [7:0] wb_dat_i;
output [7:0] wb_dat_o;
input wb_cyc_i;
input wb_stb_i;
input wb_we_i;
input [7:0] wb_adr_i;
output wb_ack_o;
reg wb_ack_o;
reg cs_sync1;
reg cs_sync2;
reg cs_sync3;
reg cs_ack1;
reg cs_ack2;
reg cs_ack3;
reg cs_sync_rst1;
reg cs_sync_rst2;
wire cs_can_i;
`else
input rst_i;
input ale_i;
input rd_i;
input wr_i;
inout [7:0] port_0_io;
input cs_can_i;
reg [7:0] addr_latched;
reg wr_i_q;
reg rd_i_q;
`endif
input clk_i;
input rx_i;
output tx_o;
output bus_off_on;
output irq_on;
output clkout_o;
// Bist
`ifdef CAN_BIST
input mbist_si_i; // bist scan serial in
output mbist_so_o; // bist scan serial out
input [`CAN_MBIST_CTRL_WIDTH - 1:0] mbist_ctrl_i; // bist chain shift control
`endif
reg data_out_fifo_selected;
wire [7:0] data_out_fifo;
wire [7:0] data_out_regs;
/* Mode register */
wire reset_mode;
wire listen_only_mode;
wire acceptance_filter_mode;
wire self_test_mode;
/* Command register */
wire release_buffer;
wire tx_request;
wire abort_tx;
wire self_rx_request;
wire single_shot_transmission;
wire tx_state;
wire tx_state_q;
wire overload_request;
wire overload_frame;
/* Arbitration Lost Capture Register */
wire read_arbitration_lost_capture_reg;
/* Error Code Capture Register */
wire read_error_code_capture_reg;
wire [7:0] error_capture_code;
/* Bus Timing 0 register */
wire [5:0] baud_r_presc;
wire [1:0] sync_jump_width;
/* Bus Timing 1 register */
wire [3:0] time_segment1;
wire [2:0] time_segment2;
wire triple_sampling;
/* Error Warning Limit register */
wire [7:0] error_warning_limit;
/* Rx Error Counter register */
wire we_rx_err_cnt;
/* Tx Error Counter register */
wire we_tx_err_cnt;
/* Clock Divider register */
wire extended_mode;
/* This section is for BASIC and EXTENDED mode */
/* Acceptance code register */
wire [7:0] acceptance_code_0;
/* Acceptance mask register */
wire [7:0] acceptance_mask_0;
/* End: This section is for BASIC and EXTENDED mode */
/* This section is for EXTENDED mode */
/* Acceptance code register */
wire [7:0] acceptance_code_1;
wire [7:0] acceptance_code_2;
wire [7:0] acceptance_code_3;
/* Acceptance mask register */
wire [7:0] acceptance_mask_1;
wire [7:0] acceptance_mask_2;
wire [7:0] acceptance_mask_3;
/* End: This section is for EXTENDED mode */
/* Tx data registers. Holding identifier (basic mode), tx frame information (extended mode) and data */
wire [7:0] tx_data_0;
wire [7:0] tx_data_1;
wire [7:0] tx_data_2;
wire [7:0] tx_data_3;
wire [7:0] tx_data_4;
wire [7:0] tx_data_5;
wire [7:0] tx_data_6;
wire [7:0] tx_data_7;
wire [7:0] tx_data_8;
wire [7:0] tx_data_9;
wire [7:0] tx_data_10;
wire [7:0] tx_data_11;
wire [7:0] tx_data_12;
/* End: Tx data registers */
wire cs;
/* Output signals from can_btl module */
wire sample_point;
wire sampled_bit;
wire sampled_bit_q;
wire tx_point;
wire hard_sync;
/* output from can_bsp module */
wire rx_idle;
wire transmitting;
wire transmitter;
wire go_rx_inter;
wire not_first_bit_of_inter;
wire set_reset_mode;
wire node_bus_off;
wire error_status;
wire [7:0] rx_err_cnt;
wire [7:0] tx_err_cnt;
wire rx_err_cnt_dummy; // The MSB is not displayed. It is just used for easier calculation (no counter overflow).
wire tx_err_cnt_dummy; // The MSB is not displayed. It is just used for easier calculation (no counter overflow).
wire transmit_status;
wire receive_status;
wire tx_successful;
wire need_to_tx;
wire overrun;
wire info_empty;
wire set_bus_error_irq;
wire set_arbitration_lost_irq;
wire [4:0] arbitration_lost_capture;
wire node_error_passive;
wire node_error_active;
wire [6:0] rx_message_counter;
wire tx_next;
wire go_overload_frame;
wire go_error_frame;
wire go_tx;
wire send_ack;
wire rst;
wire we;
wire [7:0] addr;
wire [7:0] data_in;
reg [7:0] data_out;
reg rx_sync_tmp;
reg rx_sync;
/* Connecting can_registers module */
can_registers i_can_registers
(
.clk(clk_i),
.rst(rst),
.cs(cs),
.we(we),
.addr(addr),
.data_in(data_in),
.data_out(data_out_regs),
.irq_n(irq_on),
.sample_point(sample_point),
.transmitting(transmitting),
.set_reset_mode(set_reset_mode),
.node_bus_off(node_bus_off),
.error_status(error_status),
.rx_err_cnt(rx_err_cnt),
.tx_err_cnt(tx_err_cnt),
.transmit_status(transmit_status),
.receive_status(receive_status),
.tx_successful(tx_successful),
.need_to_tx(need_to_tx),
.overrun(overrun),
.info_empty(info_empty),
.set_bus_error_irq(set_bus_error_irq),
.set_arbitration_lost_irq(set_arbitration_lost_irq),
.arbitration_lost_capture(arbitration_lost_capture),
.node_error_passive(node_error_passive),
.node_error_active(node_error_active),
.rx_message_counter(rx_message_counter),
/* Mode register */
.reset_mode(reset_mode),
.listen_only_mode(listen_only_mode),
.acceptance_filter_mode(acceptance_filter_mode),
.self_test_mode(self_test_mode),
/* Command register */
.clear_data_overrun(),
.release_buffer(release_buffer),
.abort_tx(abort_tx),
.tx_request(tx_request),
.self_rx_request(self_rx_request),
.single_shot_transmission(single_shot_transmission),
.tx_state(tx_state),
.tx_state_q(tx_state_q),
.overload_request(overload_request),
.overload_frame(overload_frame),
/* Arbitration Lost Capture Register */
.read_arbitration_lost_capture_reg(read_arbitration_lost_capture_reg),
/* Error Code Capture Register */
.read_error_code_capture_reg(read_error_code_capture_reg),
.error_capture_code(error_capture_code),
/* Bus Timing 0 register */
.baud_r_presc(baud_r_presc),
.sync_jump_width(sync_jump_width),
/* Bus Timing 1 register */
.time_segment1(time_segment1),
.time_segment2(time_segment2),
.triple_sampling(triple_sampling),
/* Error Warning Limit register */
.error_warning_limit(error_warning_limit),
/* Rx Error Counter register */
.we_rx_err_cnt(we_rx_err_cnt),
/* Tx Error Counter register */
.we_tx_err_cnt(we_tx_err_cnt),
/* Clock Divider register */
.extended_mode(extended_mode),
.clkout(clkout_o),
/* This section is for BASIC and EXTENDED mode */
/* Acceptance code register */
.acceptance_code_0(acceptance_code_0),
/* Acceptance mask register */
.acceptance_mask_0(acceptance_mask_0),
/* End: This section is for BASIC and EXTENDED mode */
/* This section is for EXTENDED mode */
/* Acceptance code register */
.acceptance_code_1(acceptance_code_1),
.acceptance_code_2(acceptance_code_2),
.acceptance_code_3(acceptance_code_3),
/* Acceptance mask register */
.acceptance_mask_1(acceptance_mask_1),
.acceptance_mask_2(acceptance_mask_2),
.acceptance_mask_3(acceptance_mask_3),
/* End: This section is for EXTENDED mode */
/* Tx data registers. Holding identifier (basic mode), tx frame information (extended mode) and data */
.tx_data_0(tx_data_0),
.tx_data_1(tx_data_1),
.tx_data_2(tx_data_2),
.tx_data_3(tx_data_3),
.tx_data_4(tx_data_4),
.tx_data_5(tx_data_5),
.tx_data_6(tx_data_6),
.tx_data_7(tx_data_7),
.tx_data_8(tx_data_8),
.tx_data_9(tx_data_9),
.tx_data_10(tx_data_10),
.tx_data_11(tx_data_11),
.tx_data_12(tx_data_12)
/* End: Tx data registers */
);
/* Connecting can_btl module */
can_btl i_can_btl
(
.clk(clk_i),
.rst(rst),
.rx(rx_sync),
.tx(tx_o),
/* Bus Timing 0 register */
.baud_r_presc(baud_r_presc),
.sync_jump_width(sync_jump_width),
/* Bus Timing 1 register */
.time_segment1(time_segment1),
.time_segment2(time_segment2),
.triple_sampling(triple_sampling),
/* Output signals from this module */
.sample_point(sample_point),
.sampled_bit(sampled_bit),
.sampled_bit_q(sampled_bit_q),
.tx_point(tx_point),
.hard_sync(hard_sync),
/* output from can_bsp module */
.rx_idle(rx_idle),
.rx_inter(rx_inter),
.transmitting(transmitting),
.transmitter(transmitter),
.go_rx_inter(go_rx_inter),
.tx_next(tx_next),
.go_overload_frame(go_overload_frame),
.go_error_frame(go_error_frame),
.go_tx(go_tx),
.send_ack(send_ack),
.node_error_passive(node_error_passive)
);
can_bsp i_can_bsp
(
.clk(clk_i),
.rst(rst),
/* From btl module */
.sample_point(sample_point),
.sampled_bit(sampled_bit),
.sampled_bit_q(sampled_bit_q),
.tx_point(tx_point),
.hard_sync(hard_sync),
.addr(addr),
.data_in(data_in),
.data_out(data_out_fifo),
.fifo_selected(data_out_fifo_selected),
/* Mode register */
.reset_mode(reset_mode),
.listen_only_mode(listen_only_mode),
.acceptance_filter_mode(acceptance_filter_mode),
.self_test_mode(self_test_mode),
/* Command register */
.release_buffer(release_buffer),
.tx_request(tx_request),
.abort_tx(abort_tx),
.self_rx_request(self_rx_request),
.single_shot_transmission(single_shot_transmission),
.tx_state(tx_state),
.tx_state_q(tx_state_q),
.overload_request(overload_request),
.overload_frame(overload_frame),
/* Arbitration Lost Capture Register */
.read_arbitration_lost_capture_reg(read_arbitration_lost_capture_reg),
/* Error Code Capture Register */
.read_error_code_capture_reg(read_error_code_capture_reg),
.error_capture_code(error_capture_code),
/* Error Warning Limit register */
.error_warning_limit(error_warning_limit),
/* Rx Error Counter register */
.we_rx_err_cnt(we_rx_err_cnt),
/* Tx Error Counter register */
.we_tx_err_cnt(we_tx_err_cnt),
/* Clock Divider register */
.extended_mode(extended_mode),
/* output from can_bsp module */
.rx_idle(rx_idle),
.transmitting(transmitting),
.transmitter(transmitter),
.go_rx_inter(go_rx_inter),
.not_first_bit_of_inter(not_first_bit_of_inter),
.rx_inter(rx_inter),
.set_reset_mode(set_reset_mode),
.node_bus_off(node_bus_off),
.error_status(error_status),
.rx_err_cnt({rx_err_cnt_dummy, rx_err_cnt[7:0]}), // The MSB is not displayed. It is just used for easier calculation (no counter overflow).
.tx_err_cnt({tx_err_cnt_dummy, tx_err_cnt[7:0]}), // The MSB is not displayed. It is just used for easier calculation (no counter overflow).
.transmit_status(transmit_status),
.receive_status(receive_status),
.tx_successful(tx_successful),
.need_to_tx(need_to_tx),
.overrun(overrun),
.info_empty(info_empty),
.set_bus_error_irq(set_bus_error_irq),
.set_arbitration_lost_irq(set_arbitration_lost_irq),
.arbitration_lost_capture(arbitration_lost_capture),
.node_error_passive(node_error_passive),
.node_error_active(node_error_active),
.rx_message_counter(rx_message_counter),
/* This section is for BASIC and EXTENDED mode */
/* Acceptance code register */
.acceptance_code_0(acceptance_code_0),
/* Acceptance mask register */
.acceptance_mask_0(acceptance_mask_0),
/* End: This section is for BASIC and EXTENDED mode */
/* This section is for EXTENDED mode */
/* Acceptance code register */
.acceptance_code_1(acceptance_code_1),
.acceptance_code_2(acceptance_code_2),
.acceptance_code_3(acceptance_code_3),
/* Acceptance mask register */
.acceptance_mask_1(acceptance_mask_1),
.acceptance_mask_2(acceptance_mask_2),
.acceptance_mask_3(acceptance_mask_3),
/* End: This section is for EXTENDED mode */
/* Tx data registers. Holding identifier (basic mode), tx frame information (extended mode) and data */
.tx_data_0(tx_data_0),
.tx_data_1(tx_data_1),
.tx_data_2(tx_data_2),
.tx_data_3(tx_data_3),
.tx_data_4(tx_data_4),
.tx_data_5(tx_data_5),
.tx_data_6(tx_data_6),
.tx_data_7(tx_data_7),
.tx_data_8(tx_data_8),
.tx_data_9(tx_data_9),
.tx_data_10(tx_data_10),
.tx_data_11(tx_data_11),
.tx_data_12(tx_data_12),
/* End: Tx data registers */
/* Tx signal */
.tx(tx_o),
.tx_next(tx_next),
.bus_off_on(bus_off_on),
.go_overload_frame(go_overload_frame),
.go_error_frame(go_error_frame),
.go_tx(go_tx),
.send_ack(send_ack)
`ifdef CAN_BIST
,
/* BIST signals */
.mbist_si_i(mbist_si_i),
.mbist_so_o(mbist_so_o),
.mbist_ctrl_i(mbist_ctrl_i)
`endif
);
// Multiplexing wb_dat_o from registers and rx fifo
always @ (extended_mode or addr or reset_mode)
begin
if (extended_mode & (~reset_mode) & ((addr >= 8'd16) && (addr <= 8'd28)) | (~extended_mode) & ((addr >= 8'd20) && (addr <= 8'd29)))
data_out_fifo_selected = 1'b1;
else
data_out_fifo_selected = 1'b0;
end
always @ (posedge clk_i)
begin
if (cs & (~we))
begin
if (data_out_fifo_selected)
data_out <=#Tp data_out_fifo;
else
data_out <=#Tp data_out_regs;
end
end
always @ (posedge clk_i or posedge rst)
begin
if (rst)
begin
rx_sync_tmp <= 1'b1;
rx_sync <= 1'b1;
end
else
begin
rx_sync_tmp <=#Tp rx_i;
rx_sync <=#Tp rx_sync_tmp;
end
end
`ifdef CAN_WISHBONE_IF
assign cs_can_i = 1'b1;
// Combining wb_cyc_i and wb_stb_i signals to cs signal. Than synchronizing to clk_i clock domain.
always @ (posedge clk_i or posedge rst)
begin
if (rst)
begin
cs_sync1 <= 1'b0;
cs_sync2 <= 1'b0;
cs_sync3 <= 1'b0;
cs_sync_rst1 <= 1'b0;
cs_sync_rst2 <= 1'b0;
end
else
begin
cs_sync1 <=#Tp wb_cyc_i & wb_stb_i & (~cs_sync_rst2) & cs_can_i;
cs_sync2 <=#Tp cs_sync1 & (~cs_sync_rst2);
cs_sync3 <=#Tp cs_sync2 & (~cs_sync_rst2);
cs_sync_rst1 <=#Tp cs_ack3;
cs_sync_rst2 <=#Tp cs_sync_rst1;
end
end
assign cs = cs_sync2 & (~cs_sync3);
always @ (posedge wb_clk_i)
begin
cs_ack1 <=#Tp cs_sync3;
cs_ack2 <=#Tp cs_ack1;
cs_ack3 <=#Tp cs_ack2;
end
// Generating acknowledge signal
always @ (posedge wb_clk_i)
begin
wb_ack_o <=#Tp (cs_ack2 & (~cs_ack3));
end
assign rst = wb_rst_i;
assign we = wb_we_i;
assign addr = wb_adr_i;
assign data_in = wb_dat_i;
assign wb_dat_o = data_out;
`else
// Latching address
always @ (posedge clk_i or posedge rst)
begin
if (rst)
addr_latched <= 8'h0;
else if (ale_i)
addr_latched <=#Tp port_0_io;
end
// Generating delayed wr_i and rd_i signals
always @ (posedge clk_i or posedge rst)
begin
if (rst)
begin
wr_i_q <= 1'b0;
rd_i_q <= 1'b0;
end
else
begin
wr_i_q <=#Tp wr_i;
rd_i_q <=#Tp rd_i;
end
end
assign cs = ((wr_i & (~wr_i_q)) | (rd_i & (~rd_i_q))) & cs_can_i;
assign rst = rst_i;
assign we = wr_i;
assign addr = addr_latched;
assign data_in = port_0_io;
assign port_0_io = (cs_can_i & rd_i)? data_out : 8'hz;
`endif
endmodule

View File

@@ -0,0 +1,139 @@
--
-- can_vhdl_top
--
-- Wraps the verilog component for the con controller into an VHDL entity
-- The wrapper translates the 8-bit wishbone interface into an 32 bit interface.
-- Still, only 8-bit accesses are allowed.
-- @autor: Thoams Fehmel
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;
library work;
use work.wishbone.all;
use work.config.all;
entity can_vhdl_top is
generic(
memaddr : generic_addr_type;
addrmask : generic_mask_type
);
port(
clk : in std_logic;
rstn : in std_logic;
wbs_i : in wb_slv_in_type;
wbs_o : out wb_slv_out_type;
rx_i : in std_logic;
tx_o : out std_logic;
driver_en : out std_logic;
irq_on : out std_logic
);
end can_vhdl_top;
architecture Behavioral of can_vhdl_top is
component can_top is
port(
wb_clk_i : in std_logic;
wb_rst_i : in std_logic;
wb_dat_i : in std_logic_vector(7 downto 0);
wb_dat_o : out std_logic_vector(7 downto 0);
wb_cyc_i : in std_logic;
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_adr_i : in std_logic_vector(7 downto 0);
wb_ack_o : out std_logic;
clk_i : in std_logic;
rx_i : in std_logic;
tx_o : out std_logic;
bus_off_on : out std_logic;
irq_on : out std_logic;
clkout_o : out std_logic
);
end component;
signal wb_dat_i : std_logic_vector(7 downto 0);
signal wb_dat_o : std_logic_vector(7 downto 0);
signal wb_addr : std_logic_vector(7 downto 0);
signal bus_off_on : std_logic;
signal clkout_o : std_logic;
signal irq_can : std_logic;
signal irq_tmp : std_logic;
signal tx_int : std_logic;
begin
can_mod : can_top
port map(
wb_clk_i=>clk,
wb_rst_i=>rstn,
wb_dat_i=>wb_dat_i,
wb_dat_o=>wb_dat_o,
wb_cyc_i=>wbs_i.cyc,
wb_stb_i=>wbs_i.stb,
wb_we_i=>wbs_i.we,
wb_adr_i=>wb_addr,
wb_ack_o=>wbs_o.ack,
clk_i=>clk,
rx_i=>rx_i,
tx_o=>tx_int,
bus_off_on=>bus_off_on, --goes nowhere
irq_on=>irq_can,
clkout_o=>clkout_o --goes nowhere
);
wb_dat_i <=
wbs_i.dat(31 downto 24) when wbs_i.sel = "1000" else
wbs_i.dat(23 downto 16) when wbs_i.sel = "0100" else
wbs_i.dat(15 downto 8) when wbs_i.sel = "0010" else
wbs_i.dat( 7 downto 0) when wbs_i.sel = "0001" else
(others=>'0');
--assert (wbs_i.stb='0' or ((wbs_i.sel="1000") or (wbs_i.sel="0100") or (wbs_i.sel="0010") or (wbs_i.sel="0001") or (wbs_i.sel="0000"))) report "CAN wishbone itnerface only supports 8-bit accesses" severity ERROR;
wbs_o.dat(31 downto 24) <= wb_dat_o when wbs_i.sel(3) = '1' else (others=>'0');
wbs_o.dat(23 downto 16) <= wb_dat_o when wbs_i.sel(2) = '1' else (others=>'0');
wbs_o.dat(15 downto 8) <= wb_dat_o when wbs_i.sel(1) = '1' else (others=>'0');
wbs_o.dat( 7 downto 0) <= wb_dat_o when wbs_i.sel(0) = '1' else (others=>'0');
--wb_addr <= wbs_i.adr(WB_ADR_BOUND+6 downto WB_ADR_BOUND) & sel2adr(wbs_i.sel);
addr_adder: if to_unsigned(memaddr, 16)(7 downto 2) /= "000000" generate
wb_addr <= std_logic_vector(unsigned(wbs_i.adr(7 downto 2) & sel2adr(wbs_i.sel)) - to_unsigned(memaddr, 16)(7 downto 0));
end generate;
addr_forw: if to_unsigned(memaddr, 16)(7 downto 2) = "000000" generate
wb_addr(7 downto 2) <= wbs_i.adr(7 downto 2);
wb_addr(1 downto 0) <= sel2adr(wbs_i.sel);
end generate;
--convert irq : active low(can) to activ high(soc)
--interrupt generation: only active for one clk cycle after falling edge of irq_can
irq_gen: process(clk)
begin
if clk = '1' and clk'event then
if irq_tmp = '1' and irq_can = '0' then
irq_on <= '1';
else
irq_on <= '0';
end if;
irq_tmp <= irq_can;
end if;
end process;
--NOTE: address check is skipped udner the assumption that the interconnect handles it.
wbs_o.wbcfg <= wb_membar(memaddr, addrmask);
-- driver enable
tx_o <= tx_int;
driver_en <= not(tx_int);
end architecture;

62
soc/peripheral/led.vhd Normal file
View File

@@ -0,0 +1,62 @@
-- See the file "LICENSE" for the full license governing this code. --
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.lt16x32_global.all;
use work.wishbone.all;
use work.config.all;
entity wb_led is
generic(
memaddr : generic_addr_type; --:= CFG_BADR_LED;
addrmask : generic_mask_type --:= CFG_MADR_LED;
);
port(
clk : in std_logic;
rst : in std_logic;
led : out std_logic_vector(7 downto 0);
wslvi : in wb_slv_in_type;
wslvo : out wb_slv_out_type
);
end wb_led;
architecture Behavioral of wb_led is
signal data : std_logic_vector(7 downto 0);
signal ack : std_logic;
begin
process(clk)
begin
if clk'event and clk='1' then
if rst = '1' then
ack <= '0';
data <= x"0F";
else
if wslvi.stb = '1' and wslvi.cyc = '1' then
if wslvi.we='1' then
data <= dec_wb_dat(wslvi.sel,wslvi.dat)(7 downto 0);
end if;
if ack = '0' then
ack <= '1';
else
ack <= '0';
end if;
else
ack <= '0';
end if;
end if;
end if;
end process;
wslvo.dat(7 downto 0) <= data;
wslvo.dat(31 downto 8) <= (others=>'0');
led <= data;
wslvo.ack <= ack;
wslvo.wbcfg <= wb_membar(memaddr, addrmask);
end Behavioral;

View File

@@ -0,0 +1,36 @@
-- See the file "LICENSE" for the full license governing this code. --
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
library work;
use work.lt16x32_internal.all;
use work.lt16x32_global.all;
use work.wishbone.all;
use work.config.all;
package lt16soc_peripherals is
component wb_led is
generic(
memaddr : generic_addr_type;-- := CFG_BADR_LED;
addrmask : generic_mask_type-- := CFG_MADR_LED;
);
port(
clk : in std_logic;
rst : in std_logic;
led : out std_logic_vector(7 downto 0);
wslvi : in wb_slv_in_type;
wslvo : out wb_slv_out_type
);
end component;
end lt16soc_peripherals;
package body lt16soc_peripherals is
--insert function bodies
end lt16soc_peripherals;