1 ---------------------------------------------------------------------
2 -- TITLE: Plasma Misc. Package
3 -- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
4 -- DATE CREATED: 2/15/01
5 -- FILENAME: mlite_pack.vhd
6 -- PROJECT: Plasma CPU core
7 -- COPYRIGHT: Software placed into the public domain by the author.
8 -- Software 'as is' without warranty. Author liable for nothing.
10 -- Data types, constants, and add functions needed for the Plasma CPU.
11 ---------------------------------------------------------------------
13 use ieee.std_logic_1164.all;
16 constant ZERO : std_logic_vector(31 downto 0) :=
17 "00000000000000000000000000000000";
18 constant ONES : std_logic_vector(31 downto 0) :=
19 "11111111111111111111111111111111";
20 --make HIGH_Z equal to ZERO if compiler complains
21 constant HIGH_Z : std_logic_vector(31 downto 0) :=
22 "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
24 subtype alu_function_type is std_logic_vector(3 downto 0);
25 constant ALU_NOTHING : alu_function_type := "0000";
26 constant ALU_ADD : alu_function_type := "0001";
27 constant ALU_SUBTRACT : alu_function_type := "0010";
28 constant ALU_LESS_THAN : alu_function_type := "0011";
29 constant ALU_LESS_THAN_SIGNED : alu_function_type := "0100";
30 constant ALU_OR : alu_function_type := "0101";
31 constant ALU_AND : alu_function_type := "0110";
32 constant ALU_XOR : alu_function_type := "0111";
33 constant ALU_NOR : alu_function_type := "1000";
35 subtype shift_function_type is std_logic_vector(1 downto 0);
36 constant SHIFT_NOTHING : shift_function_type := "00";
37 constant SHIFT_LEFT_UNSIGNED : shift_function_type := "01";
38 constant SHIFT_RIGHT_SIGNED : shift_function_type := "11";
39 constant SHIFT_RIGHT_UNSIGNED : shift_function_type := "10";
41 subtype mult_function_type is std_logic_vector(3 downto 0);
42 constant MULT_NOTHING : mult_function_type := "0000";
43 constant MULT_READ_LO : mult_function_type := "0001";
44 constant MULT_READ_HI : mult_function_type := "0010";
45 constant MULT_WRITE_LO : mult_function_type := "0011";
46 constant MULT_WRITE_HI : mult_function_type := "0100";
47 constant MULT_MULT : mult_function_type := "0101";
48 constant MULT_SIGNED_MULT : mult_function_type := "0110";
49 constant MULT_DIVIDE : mult_function_type := "0111";
50 constant MULT_SIGNED_DIVIDE : mult_function_type := "1000";
52 subtype a_source_type is std_logic_vector(1 downto 0);
53 constant A_FROM_REG_SOURCE : a_source_type := "00";
54 constant A_FROM_IMM10_6 : a_source_type := "01";
55 constant A_FROM_PC : a_source_type := "10";
57 subtype b_source_type is std_logic_vector(1 downto 0);
58 constant B_FROM_REG_TARGET : b_source_type := "00";
59 constant B_FROM_IMM : b_source_type := "01";
60 constant B_FROM_SIGNED_IMM : b_source_type := "10";
61 constant B_FROM_IMMX4 : b_source_type := "11";
63 subtype c_source_type is std_logic_vector(2 downto 0);
64 constant C_FROM_NULL : c_source_type := "000";
65 constant C_FROM_ALU : c_source_type := "001";
66 constant C_FROM_SHIFT : c_source_type := "001"; --same as alu
67 constant C_FROM_MULT : c_source_type := "001"; --same as alu
68 constant C_FROM_MEMORY : c_source_type := "010";
69 constant C_FROM_PC : c_source_type := "011";
70 constant C_FROM_PC_PLUS4 : c_source_type := "100";
71 constant C_FROM_IMM_SHIFT16: c_source_type := "101";
72 constant C_FROM_REG_SOURCEN: c_source_type := "110";
74 subtype pc_source_type is std_logic_vector(1 downto 0);
75 constant FROM_INC4 : pc_source_type := "00";
76 constant FROM_OPCODE25_0 : pc_source_type := "01";
77 constant FROM_BRANCH : pc_source_type := "10";
78 constant FROM_LBRANCH : pc_source_type := "11";
80 subtype branch_function_type is std_logic_vector(2 downto 0);
81 constant BRANCH_LTZ : branch_function_type := "000";
82 constant BRANCH_LEZ : branch_function_type := "001";
83 constant BRANCH_EQ : branch_function_type := "010";
84 constant BRANCH_NE : branch_function_type := "011";
85 constant BRANCH_GEZ : branch_function_type := "100";
86 constant BRANCH_GTZ : branch_function_type := "101";
87 constant BRANCH_YES : branch_function_type := "110";
88 constant BRANCH_NO : branch_function_type := "111";
90 -- mode(32=1,16=2,8=3), signed, write
91 subtype mem_source_type is std_logic_vector(3 downto 0);
92 constant MEM_FETCH : mem_source_type := "0000";
93 constant MEM_READ32 : mem_source_type := "0100";
94 constant MEM_WRITE32 : mem_source_type := "0101";
95 constant MEM_READ16 : mem_source_type := "1000";
96 constant MEM_READ16S : mem_source_type := "1010";
97 constant MEM_WRITE16 : mem_source_type := "1001";
98 constant MEM_READ8 : mem_source_type := "1100";
99 constant MEM_READ8S : mem_source_type := "1110";
100 constant MEM_WRITE8 : mem_source_type := "1101";
102 function bv_adder(a : in std_logic_vector;
103 b : in std_logic_vector;
104 do_add: in std_logic) return std_logic_vector;
105 function bv_negate(a : in std_logic_vector) return std_logic_vector;
106 function bv_increment(a : in std_logic_vector(31 downto 2)
107 ) return std_logic_vector;
108 function bv_inc(a : in std_logic_vector
109 ) return std_logic_vector;
114 LPM_WIDTH : natural; -- MUST be greater than 0
115 LPM_WIDTHAD : natural; -- MUST be greater than 0
116 LPM_NUMWORDS : natural := 0;
117 LPM_INDATA : string := "REGISTERED";
118 LPM_OUTDATA : string := "REGISTERED";
119 LPM_RDADDRESS_CONTROL : string := "REGISTERED";
120 LPM_WRADDRESS_CONTROL : string := "REGISTERED";
121 LPM_FILE : string := "UNUSED";
122 LPM_TYPE : string := "LPM_RAM_DP";
123 USE_EAB : string := "OFF";
124 INTENDED_DEVICE_FAMILY : string := "UNUSED";
125 RDEN_USED : string := "TRUE";
126 LPM_HINT : string := "UNUSED");
128 RDCLOCK : in std_logic := '0';
129 RDCLKEN : in std_logic := '1';
130 RDADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0);
131 RDEN : in std_logic := '1';
132 DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
133 WRADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0);
135 WRCLOCK : in std_logic := '0';
136 WRCLKEN : in std_logic := '1';
137 Q : out std_logic_vector(LPM_WIDTH-1 downto 0));
143 LPM_WIDTH : natural; -- MUST be greater than 0
144 LPM_WIDTHAD : natural; -- MUST be greater than 0
145 LPM_NUMWORDS : natural := 0;
146 LPM_INDATA : string := "REGISTERED";
147 LPM_ADDRESS_CONTROL: string := "REGISTERED";
148 LPM_OUTDATA : string := "REGISTERED";
149 LPM_FILE : string := "UNUSED";
150 LPM_TYPE : string := "LPM_RAM_DQ";
151 USE_EAB : string := "OFF";
152 INTENDED_DEVICE_FAMILY : string := "UNUSED";
153 LPM_HINT : string := "UNUSED");
155 DATA : in std_logic_vector(LPM_WIDTH-1 downto 0);
156 ADDRESS : in std_logic_vector(LPM_WIDTHAD-1 downto 0);
157 INCLOCK : in std_logic := '0';
158 OUTCLOCK : in std_logic := '0';
160 Q : out std_logic_vector(LPM_WIDTH-1 downto 0));
165 -- synthesis translate_off
166 generic (INIT : bit_vector := X"16");
167 -- synthesis translate_on
168 port (DPO : out STD_ULOGIC;
169 SPO : out STD_ULOGIC;
175 DPRA0 : in STD_ULOGIC;
176 DPRA1 : in STD_ULOGIC;
177 DPRA2 : in STD_ULOGIC;
178 DPRA3 : in STD_ULOGIC;
179 WCLK : in STD_ULOGIC;
183 -- For Xilinx Virtex-5
185 -- synthesis translate_off
186 generic (INIT : bit_vector := X"32");
187 -- synthesis translate_on
188 port (DPO : out STD_ULOGIC;
189 SPO : out STD_ULOGIC;
196 DPRA0 : in STD_ULOGIC;
197 DPRA1 : in STD_ULOGIC;
198 DPRA2 : in STD_ULOGIC;
199 DPRA3 : in STD_ULOGIC;
200 DPRA4 : in STD_ULOGIC;
201 WCLK : in STD_ULOGIC;
206 port(clk : in std_logic;
207 reset_in : in std_logic;
208 pc_new : in std_logic_vector(31 downto 2);
209 take_branch : in std_logic;
210 pause_in : in std_logic;
211 opcode25_0 : in std_logic_vector(25 downto 0);
212 pc_source : in pc_source_type;
213 pc_future : out std_logic_vector(31 downto 2);
214 pc_current : out std_logic_vector(31 downto 2);
215 pc_plus4 : out std_logic_vector(31 downto 2));
219 port(clk : in std_logic;
220 reset_in : in std_logic;
221 pause_in : in std_logic;
222 nullify_op : in std_logic;
223 address_pc : in std_logic_vector(31 downto 2);
224 opcode_out : out std_logic_vector(31 downto 0);
226 address_in : in std_logic_vector(31 downto 0);
227 mem_source : in mem_source_type;
228 data_write : in std_logic_vector(31 downto 0);
229 data_read : out std_logic_vector(31 downto 0);
230 pause_out : out std_logic;
232 address_next : out std_logic_vector(31 downto 2);
233 byte_we_next : out std_logic_vector(3 downto 0);
235 address : out std_logic_vector(31 downto 2);
236 byte_we : out std_logic_vector(3 downto 0);
237 data_w : out std_logic_vector(31 downto 0);
238 data_r : in std_logic_vector(31 downto 0));
242 port(opcode : in std_logic_vector(31 downto 0);
243 intr_signal : in std_logic;
244 rs_index : out std_logic_vector(5 downto 0);
245 rt_index : out std_logic_vector(5 downto 0);
246 rd_index : out std_logic_vector(5 downto 0);
247 imm_out : out std_logic_vector(15 downto 0);
248 alu_func : out alu_function_type;
249 shift_func : out shift_function_type;
250 mult_func : out mult_function_type;
251 branch_func : out branch_function_type;
252 a_source_out : out a_source_type;
253 b_source_out : out b_source_type;
254 c_source_out : out c_source_type;
255 pc_source_out: out pc_source_type;
256 mem_source_out:out mem_source_type;
257 exception_out: out std_logic);
261 generic(memory_type : string := "XILINX_16X");
262 port(clk : in std_logic;
263 reset_in : in std_logic;
264 pause : in std_logic;
265 rs_index : in std_logic_vector(5 downto 0);
266 rt_index : in std_logic_vector(5 downto 0);
267 rd_index : in std_logic_vector(5 downto 0);
268 reg_source_out : out std_logic_vector(31 downto 0);
269 reg_target_out : out std_logic_vector(31 downto 0);
270 reg_dest_new : in std_logic_vector(31 downto 0);
271 intr_enable : out std_logic);
275 port(imm_in : in std_logic_vector(15 downto 0);
276 reg_source : in std_logic_vector(31 downto 0);
277 a_mux : in a_source_type;
278 a_out : out std_logic_vector(31 downto 0);
280 reg_target : in std_logic_vector(31 downto 0);
281 b_mux : in b_source_type;
282 b_out : out std_logic_vector(31 downto 0);
284 c_bus : in std_logic_vector(31 downto 0);
285 c_memory : in std_logic_vector(31 downto 0);
286 c_pc : in std_logic_vector(31 downto 2);
287 c_pc_plus4 : in std_logic_vector(31 downto 2);
288 c_mux : in c_source_type;
289 reg_dest_out : out std_logic_vector(31 downto 0);
291 branch_func : in branch_function_type;
292 take_branch : out std_logic);
296 generic(alu_type : string := "DEFAULT");
297 port(a_in : in std_logic_vector(31 downto 0);
298 b_in : in std_logic_vector(31 downto 0);
299 alu_function : in alu_function_type;
300 c_alu : out std_logic_vector(31 downto 0));
304 generic(shifter_type : string := "DEFAULT" );
305 port(value : in std_logic_vector(31 downto 0);
306 shift_amount : in std_logic_vector(4 downto 0);
307 shift_func : in shift_function_type;
308 c_shift : out std_logic_vector(31 downto 0));
312 generic(mult_type : string := "DEFAULT");
313 port(clk : in std_logic;
314 reset_in : in std_logic;
315 a, b : in std_logic_vector(31 downto 0);
316 mult_func : in mult_function_type;
317 c_mult : out std_logic_vector(31 downto 0);
318 pause_out : out std_logic);
322 port(clk : in std_logic;
323 reset : in std_logic;
324 a_bus : in std_logic_vector(31 downto 0);
325 a_busD : out std_logic_vector(31 downto 0);
326 b_bus : in std_logic_vector(31 downto 0);
327 b_busD : out std_logic_vector(31 downto 0);
328 alu_func : in alu_function_type;
329 alu_funcD : out alu_function_type;
330 shift_func : in shift_function_type;
331 shift_funcD : out shift_function_type;
332 mult_func : in mult_function_type;
333 mult_funcD : out mult_function_type;
334 reg_dest : in std_logic_vector(31 downto 0);
335 reg_destD : out std_logic_vector(31 downto 0);
336 rd_index : in std_logic_vector(5 downto 0);
337 rd_indexD : out std_logic_vector(5 downto 0);
339 rs_index : in std_logic_vector(5 downto 0);
340 rt_index : in std_logic_vector(5 downto 0);
341 pc_source : in pc_source_type;
342 mem_source : in mem_source_type;
343 a_source : in a_source_type;
344 b_source : in b_source_type;
345 c_source : in c_source_type;
346 c_bus : in std_logic_vector(31 downto 0);
347 pause_any : in std_logic;
348 pause_pipeline : out std_logic);
352 generic(memory_type : string := "XILINX_16X"; --ALTERA_LPM, or DUAL_PORT_
353 mult_type : string := "DEFAULT";
354 shifter_type : string := "DEFAULT";
355 alu_type : string := "DEFAULT";
356 pipeline_stages : natural := 2); --2 or 3
357 port(clk : in std_logic;
358 reset_in : in std_logic;
359 intr_in : in std_logic;
361 address_next : out std_logic_vector(31 downto 2); --for synch ram
362 byte_we_next : out std_logic_vector(3 downto 0);
364 address : out std_logic_vector(31 downto 2);
365 byte_we : out std_logic_vector(3 downto 0);
366 data_w : out std_logic_vector(31 downto 0);
367 data_r : in std_logic_vector(31 downto 0);
368 mem_pause : in std_logic);
372 generic(memory_type : string := "DEFAULT");
373 port(clk : in std_logic;
374 reset : in std_logic;
375 address_next : in std_logic_vector(31 downto 2);
376 byte_we_next : in std_logic_vector(3 downto 0);
377 cpu_address : in std_logic_vector(31 downto 2);
378 mem_busy : in std_logic;
380 cache_access : out std_logic; --access 4KB cache
381 cache_checking : out std_logic; --checking if cache hit
382 cache_miss : out std_logic); --cache miss
383 end component; --cache
386 generic(memory_type : string := "DEFAULT");
387 port(clk : in std_logic;
388 enable : in std_logic;
389 write_byte_enable : in std_logic_vector(3 downto 0);
390 address : in std_logic_vector(31 downto 2);
391 data_write : in std_logic_vector(31 downto 0);
392 data_read : out std_logic_vector(31 downto 0));
396 generic(log_file : string := "UNUSED");
397 port(clk : in std_logic;
398 reset : in std_logic;
399 enable_read : in std_logic;
400 enable_write : in std_logic;
401 data_in : in std_logic_vector(7 downto 0);
402 data_out : out std_logic_vector(7 downto 0);
403 uart_read : in std_logic;
404 uart_write : out std_logic;
405 busy_write : out std_logic;
406 data_avail : out std_logic);
407 end component; --uart
410 port(clk : in std_logic; --25 MHz
411 reset : in std_logic;
412 enable_eth : in std_logic;
413 select_eth : in std_logic;
414 rec_isr : out std_logic;
415 send_isr : out std_logic;
417 address : out std_logic_vector(31 downto 2); --to DDR
418 byte_we : out std_logic_vector(3 downto 0);
419 data_write : out std_logic_vector(31 downto 0);
420 data_read : in std_logic_vector(31 downto 0);
421 pause_in : in std_logic;
423 mem_address : in std_logic_vector(31 downto 2); --from CPU
424 mem_byte_we : in std_logic_vector(3 downto 0);
425 data_w : in std_logic_vector(31 downto 0);
426 pause_out : out std_logic;
428 E_RX_CLK : in std_logic; --2.5 MHz receive
429 E_RX_DV : in std_logic; --data valid
430 E_RXD : in std_logic_vector(3 downto 0); --receive nibble
431 E_TX_CLK : in std_logic; --2.5 MHz transmit
432 E_TX_EN : out std_logic; --transmit enable
433 E_TXD : out std_logic_vector(3 downto 0)); --transmit nibble
434 end component; --eth_dma
437 generic(memory_type : string := "XILINX_X16"; --"DUAL_PORT_" "ALTERA_LPM";
438 log_file : string := "UNUSED";
439 ethernet : std_logic := '0';
440 use_cache : std_logic := '0');
441 port(clk : in std_logic;
442 reset : in std_logic;
443 uart_write : out std_logic;
444 uart_read : in std_logic;
446 address : out std_logic_vector(31 downto 2);
447 byte_we : out std_logic_vector(3 downto 0);
448 data_write : out std_logic_vector(31 downto 0);
449 data_read : in std_logic_vector(31 downto 0);
450 mem_pause_in : in std_logic;
451 no_ddr_start : out std_logic;
452 no_ddr_stop : out std_logic;
454 gpio0_out : out std_logic_vector(31 downto 0);
455 gpioA_in : in std_logic_vector(31 downto 0));
456 end component; --plasma
459 port(clk : in std_logic;
460 clk_2x : in std_logic;
461 reset_in : in std_logic;
463 address : in std_logic_vector(25 downto 2);
464 byte_we : in std_logic_vector(3 downto 0);
465 data_w : in std_logic_vector(31 downto 0);
466 data_r : out std_logic_vector(31 downto 0);
467 active : in std_logic;
468 no_start : in std_logic;
469 no_stop : in std_logic;
470 pause : out std_logic;
472 SD_CK_P : out std_logic; --clock_positive
473 SD_CK_N : out std_logic; --clock_negative
474 SD_CKE : out std_logic; --clock_enable
476 SD_BA : out std_logic_vector(1 downto 0); --bank_address
477 SD_A : out std_logic_vector(12 downto 0); --address(row or col)
478 SD_CS : out std_logic; --chip_select
479 SD_RAS : out std_logic; --row_address_strobe
480 SD_CAS : out std_logic; --column_address_strobe
481 SD_WE : out std_logic; --write_enable
483 SD_DQ : inout std_logic_vector(15 downto 0); --data
484 SD_UDM : out std_logic; --upper_byte_enable
485 SD_UDQS : inout std_logic; --upper_data_strobe
486 SD_LDM : out std_logic; --low_byte_enable
487 SD_LDQS : inout std_logic); --low_data_strobe
490 end; --package mlite_pack
493 package body mlite_pack is
495 function bv_adder(a : in std_logic_vector;
496 b : in std_logic_vector;
497 do_add: in std_logic) return std_logic_vector is
498 variable carry_in : std_logic;
499 variable bb : std_logic_vector(a'length-1 downto 0);
500 variable result : std_logic_vector(a'length downto 0);
509 for index in 0 to a'length-1 loop
510 result(index) := a(index) xor bb(index) xor carry_in;
511 carry_in := (carry_in and (a(index) or bb(index))) or
512 (a(index) and bb(index));
514 result(a'length) := carry_in xnor do_add;
519 function bv_negate(a : in std_logic_vector) return std_logic_vector is
520 variable carry_in : std_logic;
521 variable not_a : std_logic_vector(a'length-1 downto 0);
522 variable result : std_logic_vector(a'length-1 downto 0);
526 for index in a'reverse_range loop
527 result(index) := not_a(index) xor carry_in;
528 carry_in := carry_in and not_a(index);
534 function bv_increment(a : in std_logic_vector(31 downto 2)
535 ) return std_logic_vector is
536 variable carry_in : std_logic;
537 variable result : std_logic_vector(31 downto 2);
540 for index in 2 to 31 loop
541 result(index) := a(index) xor carry_in;
542 carry_in := a(index) and carry_in;
548 function bv_inc(a : in std_logic_vector
549 ) return std_logic_vector is
550 variable carry_in : std_logic;
551 variable result : std_logic_vector(a'length-1 downto 0);
554 for index in 0 to a'length-1 loop
555 result(index) := a(index) xor carry_in;
556 carry_in := a(index) and carry_in;