Disabled external gits

This commit is contained in:
2022-04-07 18:43:21 +02:00
parent 182267a8cb
commit 88cb3426ad
1067 changed files with 102374 additions and 6 deletions

139
cs208-ca/vhdl/ALU.vhd Executable file
View File

@@ -0,0 +1,139 @@
-- Copyright (C) 1991-2013 Altera Corporation
-- Your use of Altera Corporation's design tools, logic functions
-- and other software and tools, and its AMPP partner logic
-- functions, and any output files from any of the foregoing
-- (including device programming or simulation files), and any
-- associated documentation or information are expressly subject
-- to the terms and conditions of the Altera Program License
-- Subscription Agreement, Altera MegaCore Function License
-- Agreement, or other applicable license agreement, including,
-- without limitation, that your use is for the sole purpose of
-- programming logic devices manufactured by Altera and sold by
-- Altera or its authorized distributors. Please refer to the
-- applicable agreement for further details.
-- PROGRAM "Quartus II 32-bit"
-- VERSION "Version 13.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition"
-- CREATED "Tue Oct 29 17:44:16 2013"
LIBRARY ieee;
USE ieee.std_logic_1164.all;
LIBRARY work;
ENTITY ALU IS
PORT
(
a : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
op : IN STD_LOGIC_VECTOR(5 DOWNTO 0);
s : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END ALU;
ARCHITECTURE bdf_type OF ALU IS
COMPONENT add_sub
PORT(sub_mode : IN STD_LOGIC;
a : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
carry : OUT STD_LOGIC;
zero : OUT STD_LOGIC;
r : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
COMPONENT comparator
PORT(carry : IN STD_LOGIC;
zero : IN STD_LOGIC;
a_31 : IN STD_LOGIC;
b_31 : IN STD_LOGIC;
diff_31 : IN STD_LOGIC;
op : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
r : OUT STD_LOGIC
);
END COMPONENT;
COMPONENT logic_unit
PORT(a : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
op : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
r : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
COMPONENT multiplexer
PORT(i0 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
i1 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
i2 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
i3 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
sel : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
o : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
COMPONENT shift_unit
PORT(a : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
op : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
r : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
SIGNAL addsub : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL carry : STD_LOGIC;
SIGNAL comp_r : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL logic_r : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL shift_r : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL zero : STD_LOGIC;
BEGIN
b2v_add_sub_0 : add_sub
PORT MAP(sub_mode => op(3),
a => a,
b => b,
carry => carry,
zero => zero,
r => addsub);
b2v_comparator_0 : comparator
PORT MAP(carry => carry,
zero => zero,
a_31 => a(31),
b_31 => b(31),
diff_31 => addsub(31),
op => op(2 DOWNTO 0),
r => comp_r(0));
b2v_logic_unit_0 : logic_unit
PORT MAP(a => a,
b => b,
op => op(1 DOWNTO 0),
r => logic_r);
b2v_multiplexer_0 : multiplexer
PORT MAP(i0 => addsub,
i1 => comp_r,
i2 => logic_r,
i3 => shift_r,
sel => op(5 DOWNTO 4),
o => s);
b2v_shift_unit_0 : shift_unit
PORT MAP(a => a,
b => b(4 DOWNTO 0),
op => op(2 DOWNTO 0),
r => shift_r);
comp_r(31 DOWNTO 1) <= "0000000000000000000000000000000";
END bdf_type;

293
cs208-ca/vhdl/CPU.vhd Executable file
View File

@@ -0,0 +1,293 @@
-- Copyright (C) 1991-2013 Altera Corporation
-- Your use of Altera Corporation's design tools, logic functions
-- and other software and tools, and its AMPP partner logic
-- functions, and any output files from any of the foregoing
-- (including device programming or simulation files), and any
-- associated documentation or information are expressly subject
-- to the terms and conditions of the Altera Program License
-- Subscription Agreement, Altera MegaCore Function License
-- Agreement, or other applicable license agreement, including,
-- without limitation, that your use is for the sole purpose of
-- programming logic devices manufactured by Altera and sold by
-- Altera or its authorized distributors. Please refer to the
-- applicable agreement for further details.
-- PROGRAM "Quartus II 32-bit"
-- VERSION "Version 13.0.1 Build 232 06/12/2013 Service Pack 1 SJ Web Edition"
-- CREATED "Wed Oct 30 17:22:54 2013"
LIBRARY ieee;
USE ieee.std_logic_1164.all;
LIBRARY work;
ENTITY CPU IS
PORT
(
reset_n : IN STD_LOGIC;
clk : IN STD_LOGIC;
rddata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
write : OUT STD_LOGIC;
read : OUT STD_LOGIC;
address : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
wrdata : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END CPU;
ARCHITECTURE bdf_type OF CPU IS
COMPONENT alu
PORT(a : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
b : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
op : IN STD_LOGIC_VECTOR(5 DOWNTO 0);
s : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
COMPONENT controller
PORT(clk : IN STD_LOGIC;
reset_n : IN STD_LOGIC;
op : IN STD_LOGIC_VECTOR(5 DOWNTO 0);
opx : IN STD_LOGIC_VECTOR(5 DOWNTO 0);
branch_op : OUT STD_LOGIC;
imm_signed : OUT STD_LOGIC;
ir_en : OUT STD_LOGIC;
pc_add_imm : OUT STD_LOGIC;
pc_en : OUT STD_LOGIC;
pc_sel_a : OUT STD_LOGIC;
pc_sel_imm : OUT STD_LOGIC;
rf_wren : OUT STD_LOGIC;
sel_addr : OUT STD_LOGIC;
sel_b : OUT STD_LOGIC;
sel_mem : OUT STD_LOGIC;
sel_pc : OUT STD_LOGIC;
sel_ra : OUT STD_LOGIC;
sel_rC : OUT STD_LOGIC;
write : OUT STD_LOGIC;
read : OUT STD_LOGIC;
op_alu : OUT STD_LOGIC_VECTOR(5 DOWNTO 0)
);
END COMPONENT;
COMPONENT extend
PORT(signed : IN STD_LOGIC;
imm16 : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
imm32 : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
COMPONENT ir
PORT(clk : IN STD_LOGIC;
enable : IN STD_LOGIC;
D : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
Q : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
COMPONENT mux2x16
PORT(sel : IN STD_LOGIC;
i0 : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
i1 : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
o : OUT STD_LOGIC_VECTOR(15 DOWNTO 0)
);
END COMPONENT;
COMPONENT mux2x5
PORT(sel : IN STD_LOGIC;
i0 : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
i1 : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
o : OUT STD_LOGIC_VECTOR(4 DOWNTO 0)
);
END COMPONENT;
COMPONENT mux2x32
PORT(sel : IN STD_LOGIC;
i0 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
i1 : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
o : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
COMPONENT pc
PORT(clk : IN STD_LOGIC;
reset_n : IN STD_LOGIC;
en : IN STD_LOGIC;
sel_a : IN STD_LOGIC;
sel_imm : IN STD_LOGIC;
add_imm : IN STD_LOGIC;
a : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
imm : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
addr : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
COMPONENT register_file
PORT(clk : IN STD_LOGIC;
wren : IN STD_LOGIC;
aa : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
ab : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
aw : IN STD_LOGIC_VECTOR(4 DOWNTO 0);
wrdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
a : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
b : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
SIGNAL a : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL alu_res : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL aw : STD_LOGIC_VECTOR(4 DOWNTO 0);
SIGNAL b : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL branch_op : STD_LOGIC;
SIGNAL branch_taken : STD_LOGIC;
SIGNAL imm : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL imm_signed : STD_LOGIC;
SIGNAL instr : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL ir_en : STD_LOGIC;
SIGNAL op_alu : STD_LOGIC_VECTOR(5 DOWNTO 0);
SIGNAL op_b : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL pc_add_imm : STD_LOGIC;
SIGNAL pc_addr : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL pc_en : STD_LOGIC;
SIGNAL pc_sel_a : STD_LOGIC;
SIGNAL pc_sel_imm : STD_LOGIC;
SIGNAL pc_wren : STD_LOGIC;
SIGNAL ra : STD_LOGIC_VECTOR(4 DOWNTO 0);
SIGNAL rf_wren : STD_LOGIC;
SIGNAL sel_addr : STD_LOGIC;
SIGNAL sel_b : STD_LOGIC;
SIGNAL sel_mem : STD_LOGIC;
SIGNAL sel_pc : STD_LOGIC;
SIGNAL sel_ra : STD_LOGIC;
SIGNAL sel_rC : STD_LOGIC;
SIGNAL SYNTHESIZED_WIRE_0 : STD_LOGIC_VECTOR(4 DOWNTO 0);
SIGNAL SYNTHESIZED_WIRE_1 : STD_LOGIC;
SIGNAL SYNTHESIZED_WIRE_2 : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL SYNTHESIZED_WIRE_3 : STD_LOGIC_VECTOR(31 DOWNTO 0);
BEGIN
b2v_alu_0 : alu
PORT MAP(a => a,
b => op_b,
op => op_alu,
s => alu_res);
branch_taken <= branch_op AND alu_res(0);
b2v_controller_0 : controller
PORT MAP(clk => clk,
reset_n => reset_n,
op => instr(5 DOWNTO 0),
opx => instr(16 DOWNTO 11),
branch_op => branch_op,
imm_signed => imm_signed,
ir_en => ir_en,
pc_add_imm => pc_add_imm,
pc_en => pc_wren,
pc_sel_a => pc_sel_a,
pc_sel_imm => pc_sel_imm,
rf_wren => rf_wren,
sel_addr => sel_addr,
sel_b => sel_b,
sel_mem => sel_mem,
sel_pc => sel_pc,
sel_ra => sel_ra,
sel_rC => sel_rC,
write => write,
read => read,
op_alu => op_alu);
b2v_extend_0 : extend
PORT MAP(signed => imm_signed,
imm16 => instr(21 DOWNTO 6),
imm32 => imm);
b2v_IR_0 : ir
PORT MAP(clk => clk,
enable => ir_en,
D => rddata,
Q => instr);
b2v_mux_addr : mux2x16
PORT MAP(sel => sel_addr,
i0 => pc_addr(15 DOWNTO 0),
i1 => alu_res(15 DOWNTO 0),
o => address);
b2v_mux_aw : mux2x5
PORT MAP(sel => sel_rC,
i0 => SYNTHESIZED_WIRE_0,
i1 => instr(21 DOWNTO 17),
o => aw);
b2v_mux_b : mux2x32
PORT MAP(sel => sel_b,
i0 => imm,
i1 => b,
o => op_b);
b2v_mux_data : mux2x32
PORT MAP(sel => SYNTHESIZED_WIRE_1,
i0 => alu_res,
i1 => SYNTHESIZED_WIRE_2,
o => SYNTHESIZED_WIRE_3);
b2v_mux_mem : mux2x32
PORT MAP(sel => sel_mem,
i0 => pc_addr,
i1 => rddata,
o => SYNTHESIZED_WIRE_2);
b2v_mux_ra : mux2x5
PORT MAP(sel => sel_ra,
i0 => instr(26 DOWNTO 22),
i1 => ra,
o => SYNTHESIZED_WIRE_0);
pc_en <= pc_wren OR branch_taken;
b2v_PC_0 : pc
PORT MAP(clk => clk,
reset_n => reset_n,
en => pc_en,
sel_a => pc_sel_a,
sel_imm => pc_sel_imm,
add_imm => pc_add_imm,
a => a(15 DOWNTO 0),
imm => instr(21 DOWNTO 6),
addr => pc_addr);
SYNTHESIZED_WIRE_1 <= sel_pc OR sel_mem;
b2v_register_file_0 : register_file
PORT MAP(clk => clk,
wren => rf_wren,
aa => instr(31 DOWNTO 27),
ab => instr(26 DOWNTO 22),
aw => aw,
wrdata => SYNTHESIZED_WIRE_3,
a => a,
b => b);
wrdata <= b;
ra <= "11111";
END bdf_type;

194
cs208-ca/vhdl/GECKO.vhd Executable file
View File

@@ -0,0 +1,194 @@
-- Copyright (C) 1991-2016 Altera Corporation. All rights reserved.
-- Your use of Altera Corporation's design tools, logic functions
-- and other software and tools, and its AMPP partner logic
-- functions, and any output files from any of the foregoing
-- (including device programming or simulation files), and any
-- associated documentation or information are expressly subject
-- to the terms and conditions of the Altera Program License
-- Subscription Agreement, the Altera Quartus Prime License Agreement,
-- the Altera MegaCore Function License Agreement, or other
-- applicable license agreement, including, without limitation,
-- that your use is for the sole purpose of programming logic
-- devices manufactured by Altera and sold by Altera or its
-- authorized distributors. Please refer to the applicable
-- agreement for further details.
-- PROGRAM "Quartus Prime"
-- VERSION "Version 16.0.0 Build 211 04/27/2016 SJ Lite Edition"
-- CREATED "Tue Oct 03 14:49:59 2017"
LIBRARY ieee;
USE ieee.std_logic_1164.all;
LIBRARY work;
ENTITY GECKO IS
PORT
(
clk : IN STD_LOGIC;
reset_n : IN STD_LOGIC;
in_buttons : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
row1 : OUT STD_LOGIC_VECTOR(11 DOWNTO 0);
row2 : OUT STD_LOGIC_VECTOR(11 DOWNTO 0);
row3 : OUT STD_LOGIC_VECTOR(11 DOWNTO 0);
row4 : OUT STD_LOGIC_VECTOR(11 DOWNTO 0);
row5 : OUT STD_LOGIC_VECTOR(11 DOWNTO 0);
row6 : OUT STD_LOGIC_VECTOR(11 DOWNTO 0);
row7 : OUT STD_LOGIC_VECTOR(11 DOWNTO 0);
row8 : OUT STD_LOGIC_VECTOR(11 DOWNTO 0)
);
END GECKO;
ARCHITECTURE bdf_type OF GECKO IS
COMPONENT buttons
PORT(clk : IN STD_LOGIC;
reset_n : IN STD_LOGIC;
cs : IN STD_LOGIC;
read : IN STD_LOGIC;
write : IN STD_LOGIC;
address : IN STD_LOGIC;
buttons : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
wrdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
rddata : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
COMPONENT decoder
PORT(address : IN STD_LOGIC_VECTOR(15 DOWNTO 0);
cs_RAM : OUT STD_LOGIC;
cs_ROM : OUT STD_LOGIC;
cs_Buttons : OUT STD_LOGIC;
cs_LEDs : OUT STD_LOGIC
);
END COMPONENT;
COMPONENT cpu
PORT(clk : IN STD_LOGIC;
reset_n : IN STD_LOGIC;
rddata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
write : OUT STD_LOGIC;
read : OUT STD_LOGIC;
address : OUT STD_LOGIC_VECTOR(15 DOWNTO 0);
wrdata : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
COMPONENT leds
PORT(clk : IN STD_LOGIC;
reset_n : IN STD_LOGIC;
cs : IN STD_LOGIC;
write : IN STD_LOGIC;
read : IN STD_LOGIC;
address : IN STD_LOGIC_VECTOR(1 DOWNTO 0);
wrdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
LEDs : OUT STD_LOGIC_VECTOR(95 DOWNTO 0);
rddata : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
COMPONENT ram
PORT(clk : IN STD_LOGIC;
cs : IN STD_LOGIC;
write : IN STD_LOGIC;
read : IN STD_LOGIC;
address : IN STD_LOGIC_VECTOR(9 DOWNTO 0);
wrdata : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
rddata : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
COMPONENT rom
PORT(clk : IN STD_LOGIC;
cs : IN STD_LOGIC;
read : IN STD_LOGIC;
address : IN STD_LOGIC_VECTOR(9 DOWNTO 0);
rddata : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
SIGNAL address : STD_LOGIC_VECTOR(15 DOWNTO 0);
SIGNAL cs_Buttons : STD_LOGIC;
SIGNAL cs_LEDs : STD_LOGIC;
SIGNAL cs_RAM : STD_LOGIC;
SIGNAL cs_ROM : STD_LOGIC;
SIGNAL out_LEDs : STD_LOGIC_VECTOR(95 DOWNTO 0);
SIGNAL rddata : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL wrdata : STD_LOGIC_VECTOR(31 DOWNTO 0);
SIGNAL SYNTHESIZED_WIRE_7 : STD_LOGIC;
SIGNAL SYNTHESIZED_WIRE_8 : STD_LOGIC;
BEGIN
b2v_buttons_0 : buttons
PORT MAP(clk => clk,
reset_n => reset_n,
cs => cs_Buttons,
read => SYNTHESIZED_WIRE_7,
write => SYNTHESIZED_WIRE_8,
address => address(2),
buttons => in_buttons,
wrdata => wrdata,
rddata => rddata);
b2v_decoder_0 : decoder
PORT MAP(address => address,
cs_RAM => cs_RAM,
cs_ROM => cs_ROM,
cs_Buttons => cs_Buttons,
cs_LEDs => cs_LEDs);
b2v_inst : cpu
PORT MAP(clk => clk,
reset_n => reset_n,
rddata => rddata,
write => SYNTHESIZED_WIRE_8,
read => SYNTHESIZED_WIRE_7,
address => address,
wrdata => wrdata);
b2v_LEDs_0 : leds
PORT MAP(clk => clk,
reset_n => reset_n,
cs => cs_LEDs,
write => SYNTHESIZED_WIRE_8,
read => SYNTHESIZED_WIRE_7,
address => address(3 DOWNTO 2),
wrdata => wrdata,
LEDs => out_LEDs,
rddata => rddata);
b2v_RAM_0 : ram
PORT MAP(clk => clk,
cs => cs_RAM,
write => SYNTHESIZED_WIRE_8,
read => SYNTHESIZED_WIRE_7,
address => address(11 DOWNTO 2),
wrdata => wrdata,
rddata => rddata);
b2v_ROM_0 : rom
PORT MAP(clk => clk,
cs => cs_ROM,
read => SYNTHESIZED_WIRE_7,
address => address(11 DOWNTO 2),
rddata => rddata);
row1(11 DOWNTO 0) <= out_LEDs(11 DOWNTO 0);
row2(11 DOWNTO 0) <= out_LEDs(23 DOWNTO 12);
row3(11 DOWNTO 0) <= out_LEDs(35 DOWNTO 24);
row4(11 DOWNTO 0) <= out_LEDs(47 DOWNTO 36);
row5(11 DOWNTO 0) <= out_LEDs(59 DOWNTO 48);
row6(11 DOWNTO 0) <= out_LEDs(71 DOWNTO 60);
row7(11 DOWNTO 0) <= out_LEDs(83 DOWNTO 72);
row8(11 DOWNTO 0) <= out_LEDs(95 DOWNTO 84);
END bdf_type;

28
cs208-ca/vhdl/IR.vhd Executable file
View File

@@ -0,0 +1,28 @@
library ieee;
use ieee.std_logic_1164.all;
entity IR is
port(
clk : in std_logic;
enable : in std_logic;
D : in std_logic_vector(31 downto 0);
Q : out std_logic_vector(31 downto 0)
);
end IR;
architecture synth of IR is
signal sq : std_logic_vector(31 downto 0) := (others => '0');
begin
write : process(clk, enable) is
begin
if (rising_edge(clk) and enable = '1') then
sq <= D;
end if;
end process;
Q <= sq;
end synth;

106
cs208-ca/vhdl/LEDs.vhd Executable file
View File

@@ -0,0 +1,106 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity LEDs is
port(
-- bus interface
clk : in std_logic;
reset_n : in std_logic;
cs : in std_logic;
read : in std_logic;
write : in std_logic;
address : in std_logic_vector(1 downto 0);
rddata : out std_logic_vector(31 downto 0);
wrdata : in std_logic_vector(31 downto 0);
-- external output
LEDs : out std_logic_vector(95 downto 0)
);
end LEDs;
architecture synth of LEDs is
constant REG_LED_0_31 : std_logic_vector(1 downto 0) := "00";
constant REG_LED_32_63 : std_logic_vector(1 downto 0) := "01";
constant REG_LED_64_95 : std_logic_vector(1 downto 0) := "10";
constant REG_DUTY_CYCLE : std_logic_vector(1 downto 0) := "11";
signal reg_read : std_logic;
signal reg_address : std_logic_vector(1 downto 0);
signal counter : std_logic_vector(7 downto 0);
signal LEDs_reg : std_logic_vector(95 downto 0);
signal LEDs_FPGA4U : std_logic_vector(95 downto 0);
signal duty_cycle : std_logic_vector(7 downto 0);
begin
LEDs_FPGA4U <= LEDs_reg when counter < duty_cycle else (others => '0');
-- On FPGA4U, LEDs were addressed by column, on GECKO by row and mirrored
-- Therefore, we need to transpose the indices and flip the indeces along x
process(LEDs_FPGA4U)
variable LEDs_before_transpose: std_logic_vector(95 downto 0);
begin
for i in 0 to 95 loop
LEDs_before_transpose(i / 8 + (i mod 8) * 12) := LEDs_FPGA4U(i);
LEDs(i) <= LEDs_before_transpose((i / 12 + 1) * 12 - 1 - (i mod 12));
end loop;
end process;
-- registers
process(clk, reset_n)
begin
if (reset_n = '0') then
reg_read <= '0';
reg_address <= (others => '0');
counter <= (others => '0');
elsif (rising_edge(clk)) then
reg_read <= cs and read;
reg_address <= address;
if address /= REG_DUTY_CYCLE then
counter <= std_logic_vector(unsigned(counter) + 1);
else
counter <= (others => '0');
end if;
end if;
end process;
-- read
process(reg_read, reg_address, LEDs_reg, duty_cycle)
begin
rddata <= (others => 'Z');
if (reg_read = '1') then
rddata <= (others => '0');
case reg_address is
when REG_LED_0_31 =>
rddata <= LEDs_reg(31 downto 0);
when REG_LED_32_63 =>
rddata <= LEDs_reg(63 downto 32);
when REG_LED_64_95 =>
rddata <= LEDs_reg(95 downto 64);
when REG_DUTY_CYCLE =>
rddata(7 downto 0) <= duty_cycle;
when others =>
end case;
end if;
end process;
-- write
process(clk, reset_n)
begin
if (reset_n = '0') then
LEDs_reg <= (others => '0');
duty_cycle <= X"0F";
elsif (rising_edge(clk)) then
if (cs = '1' and write = '1') then
case address is
when REG_LED_0_31 => LEDs_reg(31 downto 0) <= wrdata;
when REG_LED_32_63 => LEDs_reg(63 downto 32) <= wrdata;
when REG_LED_64_95 => LEDs_reg(95 downto 64) <= wrdata;
when REG_DUTY_CYCLE => duty_cycle <= wrdata(7 downto 0);
when others => null;
end case;
end if;
end if;
end process;
end synth;

106
cs208-ca/vhdl/LEDs.vhd.bak Executable file
View File

@@ -0,0 +1,106 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity LEDs is
port(
-- bus interface
clk : in std_logic;
reset_n : in std_logic;
cs : in std_logic;
read : in std_logic;
write : in std_logic;
address : in std_logic_vector(1 downto 0);
rddata : out std_logic_vector(31 downto 0);
wrdata : in std_logic_vector(31 downto 0);
-- external output
LEDs : out std_logic_vector(95 downto 0)
);
end LEDs;
architecture synth of LEDs is
constant REG_LED_0_31 : std_logic_vector(1 downto 0) := "00";
constant REG_LED_32_63 : std_logic_vector(1 downto 0) := "01";
constant REG_LED_64_95 : std_logic_vector(1 downto 0) := "10";
constant REG_DUTY_CYCLE : std_logic_vector(1 downto 0) := "11";
signal reg_read : std_logic;
signal reg_address : std_logic_vector(1 downto 0);
signal counter : std_logic_vector(7 downto 0);
signal LEDs_reg : std_logic_vector(95 downto 0) ;
signal LEDs_FPGA4U : std_logic_vector(95 downto 0);
signal duty_cycle : std_logic_vector(7 downto 0);
begin
LEDs_FPGA4U <= LEDs_reg when counter < duty_cycle else (others => '0');
-- On FPGA4U, LEDs were addressed by column, on GECKO by row and mirrored
-- Therefore, we need to transpose the indices and flip the indeces along x
process(LEDs_FPGA4U)
variable LEDs_before_transpose: std_logic_vector(95 downto 0);
begin
for i in 0 to 95 loop
LEDs_before_transpose(i / 8 + (i mod 8) * 12) := LEDs_FPGA4U(i);
LEDs(i) <= LEDs_before_transpose((i / 12 + 1) * 12 - 1 - (i mod 12));
end loop;
end process;
-- registers
process(clk, reset_n)
begin
if (reset_n = '0') then
reg_read <= '0';
reg_address <= (others => '0');
counter <= (others => '0');
elsif (rising_edge(clk)) then
reg_read <= cs and read;
reg_address <= address;
if address /= REG_DUTY_CYCLE then
counter <= std_logic_vector(unsigned(counter) + 1);
else
counter <= (others => '0');
end if;
end if;
end process;
-- read
process(reg_read, reg_address, LEDs_reg, duty_cycle)
begin
rddata <= (others => 'Z');
if (reg_read = '1') then
rddata <= (others => '0');
case reg_address is
when REG_LED_0_31 =>
rddata <= LEDs_reg(31 downto 0);
when REG_LED_32_63 =>
rddata <= LEDs_reg(63 downto 32);
when REG_LED_64_95 =>
rddata <= LEDs_reg(95 downto 64);
when REG_DUTY_CYCLE =>
rddata(7 downto 0) <= duty_cycle;
when others =>
end case;
end if;
end process;
-- write
process(clk, reset_n)
begin
if (reset_n = '0') then
LEDs_reg <= (others => '0');
duty_cycle <= X"0F";
elsif (rising_edge(clk)) then
if (cs = '1' and write = '1') then
case address is
when REG_LED_0_31 => LEDs_reg(31 downto 0) <= wrdata;
when REG_LED_32_63 => LEDs_reg(63 downto 32) <= wrdata;
when REG_LED_64_95 => LEDs_reg(95 downto 64) <= wrdata;
when REG_DUTY_CYCLE => duty_cycle <= wrdata(7 downto 0);
when others => null;
end case;
end if;
end if;
end process;
end synth;

53
cs208-ca/vhdl/PC.vhd Executable file
View File

@@ -0,0 +1,53 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity PC is
port(
clk : in std_logic;
reset_n : in std_logic;
en : in std_logic;
sel_a : in std_logic;
sel_imm : in std_logic;
add_imm : in std_logic;
imm : in std_logic_vector(15 downto 0);
a : in std_logic_vector(15 downto 0);
addr : out std_logic_vector(31 downto 0)
);
end PC;
architecture synth of PC is
signal s_addr : std_logic_vector(31 downto 0);
signal n_addr : std_logic_vector(31 downto 0);
begin
inc_address : process(clk, reset_n, s_addr) is
begin
if (reset_n = '0') then
n_addr <= (others => '0');
elsif (rising_edge(clk)) then
if (en = '1') then
if (add_imm = '1') then
n_addr <= std_logic_vector(to_unsigned(to_integer(unsigned(s_addr)) + to_integer(signed(imm)),32));
else
n_addr <= std_logic_vector(unsigned(s_addr) + 4);
end if;
if(sel_imm = '1') then
n_addr <= (15 downto 0 => '0') & imm(13 downto 0) & "00";
elsif(sel_a = '1') then
n_addr <= ((15 downto 0 => '0') & a);
end if;
end if;
n_addr(1 downto 0) <= "00";
end if;
end process;
s_addr <= n_addr;
addr <= (15 downto 0 => '0') & s_addr(15 downto 0);
end synth;

53
cs208-ca/vhdl/PC.vhd.bak Executable file
View File

@@ -0,0 +1,53 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity PC is
port(
clk : in std_logic;
reset_n : in std_logic;
en : in std_logic;
sel_a : in std_logic;
sel_imm : in std_logic;
add_imm : in std_logic;
imm : in std_logic_vector(15 downto 0);
a : in std_logic_vector(15 downto 0);
addr : out std_logic_vector(31 downto 0)
);
end PC;
architecture synth of PC is
signal s_addr : std_logic_vector(31 downto 0);
signal n_addr : std_logic_vector(31 downto 0);
begin
inc_address : process(clk, reset_n, s_addr) is
begin
if (reset_n = '0') then
n_addr <= (others => '0');
elsif (rising_edge(clk)) then
if (en = '1') then
if (add_imm = '1') then
n_addr <= std_logic_vector(to_unsigned(to_integer(unsigned(s_addr)) + to_integer(signed(imm)),32));
else
n_addr <= std_logic_vector(unsigned(s_addr) + 4);
end if;
if(sel_imm = '1') then
n_addr <= (15 downto 0 => '0') & imm(13 downto 0) & "00";
elsif(sel_a = '1') then
n_addr <= ((15 downto 0 => '0') & a);
end if;
end if;
n_addr(1 downto 0) <= "00";
end if;
end process;
s_addr <= n_addr;
addr <= (15 downto 0 => '0') & n_addr(15 downto 0);
end synth;

55
cs208-ca/vhdl/RAM.vhd Executable file
View File

@@ -0,0 +1,55 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity RAM is
port(
clk : in std_logic;
cs : in std_logic;
read : in std_logic;
write : in std_logic;
address : in std_logic_vector(9 downto 0);
wrdata : in std_logic_vector(31 downto 0);
rddata : out std_logic_vector(31 downto 0));
end RAM;
architecture synth of RAM is
signal reg_read : std_logic;
signal reg_address : std_logic_vector(9 downto 0);
type reg_type is array(0 to 1023) of std_logic_vector(31 downto 0);
signal reg: reg_type := (others => (others => '0'));
begin
-- registers
process(clk)
begin
if (rising_edge(clk)) then
reg_read <= cs and read;
reg_address <= address;
end if;
end process;
-- read
process(reg_read, reg_address, reg)
begin
rddata <= (others => 'Z');
if (reg_read = '1') then
rddata <= reg(to_integer(unsigned(reg_address)));
end if;
end process;
-- write
process(clk)
begin
if (rising_edge(clk)) then
if (cs = '1' and write = '1') then
reg(to_integer(unsigned(address))) <= wrdata;
end if;
end if;
end process;
end synth;

56
cs208-ca/vhdl/ROM.vhd Executable file
View File

@@ -0,0 +1,56 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ROM is
port(
clk : in std_logic;
cs : in std_logic;
read : in std_logic;
address : in std_logic_vector(9 downto 0);
rddata : out std_logic_vector(31 downto 0)
);
end ROM;
architecture synth of ROM is
signal reg_read : std_logic;
signal reg_data : std_logic_vector(31 downto 0);
component ROM_Block
port(
address : IN STD_LOGIC_VECTOR (9 DOWNTO 0);
clock : IN STD_LOGIC := '1';
q : OUT STD_LOGIC_VECTOR (31 DOWNTO 0)
);
end component;
begin
-- romblock
romblock : ROM_Block port map(
address => address,
clock => clk,
q => reg_data
);
-- registers
process(clk)
begin
if (rising_edge(clk)) then
reg_read <= cs and read;
end if;
end process;
-- read
process(reg_read, reg_data)
begin
rddata <= (others => 'Z');
if (reg_read = '1') then
rddata <= reg_data;
end if;
end process;
end synth;

48
cs208-ca/vhdl/ROM.vhd.bak Executable file
View File

@@ -0,0 +1,48 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity ROM is
port(
clk : in std_logic;
cs : in std_logic;
read : in std_logic;
address : in std_logic_vector(9 downto 0);
rddata : out std_logic_vector(31 downto 0)
);
end ROM;
architecture synth of ROM is
signal reg_read : std_logic;
signal reg_data : std_logic_vector(31 downto 0);
component ROM_Block
port(
address : IN STD_LOGIC_VECTOR (9 DOWNTO 0);
clock : IN STD_LOGIC := '1';
q : OUT STD_LOGIC_VECTOR (31 DOWNTO 0)
);
end component;
begin
-- romblock
romblock : ROM_Block port map(
address => address,
clock => clk,
q => reg_data
);
-- registers
process(clk)
begin
if (rising_edge(clk) and cs = '1' and read = '1') then
rddata <= reg_data;
end if;
end process;
end synth;

169
cs208-ca/vhdl/ROM_Block.vhd Executable file
View File

@@ -0,0 +1,169 @@
-- megafunction wizard: %ROM: 1-PORT%
-- GENERATION: STANDARD
-- VERSION: WM1.0
-- MODULE: altsyncram
-- ============================================================
-- File Name: ROM_Block.vhd
-- Megafunction Name(s):
-- altsyncram
--
-- Simulation Library Files(s):
-- altera_mf
-- ============================================================
-- ************************************************************
-- THIS IS A WIZARD-GENERATED FILE. DO NOT EDIT THIS FILE!
--
-- 12.1 Build 177 11/07/2012 SJ Web Edition
-- ************************************************************
--Copyright (C) 1991-2012 Altera Corporation
--Your use of Altera Corporation's design tools, logic functions
--and other software and tools, and its AMPP partner logic
--functions, and any output files from any of the foregoing
--(including device programming or simulation files), and any
--associated documentation or information are expressly subject
--to the terms and conditions of the Altera Program License
--Subscription Agreement, Altera MegaCore Function License
--Agreement, or other applicable license agreement, including,
--without limitation, that your use is for the sole purpose of
--programming logic devices manufactured by Altera and sold by
--Altera or its authorized distributors. Please refer to the
--applicable agreement for further details.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
LIBRARY altera_mf;
USE altera_mf.all;
ENTITY ROM_Block IS
PORT
(
address : IN STD_LOGIC_VECTOR (9 DOWNTO 0);
clock : IN STD_LOGIC := '1';
q : OUT STD_LOGIC_VECTOR (31 DOWNTO 0)
);
END ROM_Block;
ARCHITECTURE SYN OF rom_block IS
SIGNAL sub_wire0 : STD_LOGIC_VECTOR (31 DOWNTO 0);
COMPONENT altsyncram
GENERIC (
address_aclr_a : STRING;
clock_enable_input_a : STRING;
clock_enable_output_a : STRING;
init_file : STRING;
intended_device_family : STRING;
lpm_hint : STRING;
lpm_type : STRING;
numwords_a : NATURAL;
operation_mode : STRING;
outdata_aclr_a : STRING;
outdata_reg_a : STRING;
widthad_a : NATURAL;
width_a : NATURAL;
width_byteena_a : NATURAL
);
PORT (
address_a : IN STD_LOGIC_VECTOR (9 DOWNTO 0);
clock0 : IN STD_LOGIC ;
q_a : OUT STD_LOGIC_VECTOR (31 DOWNTO 0)
);
END COMPONENT;
BEGIN
q <= sub_wire0(31 DOWNTO 0);
altsyncram_component : altsyncram
GENERIC MAP (
address_aclr_a => "NONE",
clock_enable_input_a => "BYPASS",
clock_enable_output_a => "BYPASS",
init_file => "../quartus/ROM.hex",
intended_device_family => "Cyclone IV E",
lpm_hint => "ENABLE_RUNTIME_MOD=NO",
lpm_type => "altsyncram",
numwords_a => 1024,
operation_mode => "ROM",
outdata_aclr_a => "NONE",
outdata_reg_a => "UNREGISTERED",
widthad_a => 10,
width_a => 32,
width_byteena_a => 1
)
PORT MAP (
address_a => address,
clock0 => clock,
q_a => sub_wire0
);
END SYN;
-- ============================================================
-- CNX file retrieval info
-- ============================================================
-- Retrieval info: PRIVATE: ADDRESSSTALL_A NUMERIC "0"
-- Retrieval info: PRIVATE: AclrAddr NUMERIC "0"
-- Retrieval info: PRIVATE: AclrByte NUMERIC "0"
-- Retrieval info: PRIVATE: AclrOutput NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_ENABLE NUMERIC "0"
-- Retrieval info: PRIVATE: BYTE_SIZE NUMERIC "8"
-- Retrieval info: PRIVATE: BlankMemory NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_INPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: CLOCK_ENABLE_OUTPUT_A NUMERIC "0"
-- Retrieval info: PRIVATE: Clken NUMERIC "0"
-- Retrieval info: PRIVATE: IMPLEMENT_IN_LES NUMERIC "0"
-- Retrieval info: PRIVATE: INIT_FILE_LAYOUT STRING "PORT_A"
-- Retrieval info: PRIVATE: INIT_TO_SIM_X NUMERIC "0"
-- Retrieval info: PRIVATE: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
-- Retrieval info: PRIVATE: JTAG_ENABLED NUMERIC "0"
-- Retrieval info: PRIVATE: JTAG_ID STRING "NONE"
-- Retrieval info: PRIVATE: MAXIMUM_DEPTH NUMERIC "0"
-- Retrieval info: PRIVATE: MIFfilename STRING "../quartus/ROM.hex"
-- Retrieval info: PRIVATE: NUMWORDS_A NUMERIC "1024"
-- Retrieval info: PRIVATE: RAM_BLOCK_TYPE NUMERIC "0"
-- Retrieval info: PRIVATE: RegAddr NUMERIC "1"
-- Retrieval info: PRIVATE: RegOutput NUMERIC "0"
-- Retrieval info: PRIVATE: SYNTH_WRAPPER_GEN_POSTFIX STRING "0"
-- Retrieval info: PRIVATE: SingleClock NUMERIC "1"
-- Retrieval info: PRIVATE: UseDQRAM NUMERIC "0"
-- Retrieval info: PRIVATE: WidthAddr NUMERIC "10"
-- Retrieval info: PRIVATE: WidthData NUMERIC "32"
-- Retrieval info: PRIVATE: rden NUMERIC "0"
-- Retrieval info: LIBRARY: altera_mf altera_mf.altera_mf_components.all
-- Retrieval info: CONSTANT: ADDRESS_ACLR_A STRING "NONE"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_INPUT_A STRING "BYPASS"
-- Retrieval info: CONSTANT: CLOCK_ENABLE_OUTPUT_A STRING "BYPASS"
-- Retrieval info: CONSTANT: INIT_FILE STRING "../quartus/ROM.hex"
-- Retrieval info: CONSTANT: INTENDED_DEVICE_FAMILY STRING "Cyclone IV E"
-- Retrieval info: CONSTANT: LPM_HINT STRING "ENABLE_RUNTIME_MOD=NO"
-- Retrieval info: CONSTANT: LPM_TYPE STRING "altsyncram"
-- Retrieval info: CONSTANT: NUMWORDS_A NUMERIC "1024"
-- Retrieval info: CONSTANT: OPERATION_MODE STRING "ROM"
-- Retrieval info: CONSTANT: OUTDATA_ACLR_A STRING "NONE"
-- Retrieval info: CONSTANT: OUTDATA_REG_A STRING "UNREGISTERED"
-- Retrieval info: CONSTANT: WIDTHAD_A NUMERIC "10"
-- Retrieval info: CONSTANT: WIDTH_A NUMERIC "32"
-- Retrieval info: CONSTANT: WIDTH_BYTEENA_A NUMERIC "1"
-- Retrieval info: USED_PORT: address 0 0 10 0 INPUT NODEFVAL "address[9..0]"
-- Retrieval info: USED_PORT: clock 0 0 0 0 INPUT VCC "clock"
-- Retrieval info: USED_PORT: q 0 0 32 0 OUTPUT NODEFVAL "q[31..0]"
-- Retrieval info: CONNECT: @address_a 0 0 10 0 address 0 0 10 0
-- Retrieval info: CONNECT: @clock0 0 0 0 0 clock 0 0 0 0
-- Retrieval info: CONNECT: q 0 0 32 0 @q_a 0 0 32 0
-- Retrieval info: GEN_FILE: TYPE_NORMAL ROM_Block.vhd TRUE
-- Retrieval info: GEN_FILE: TYPE_NORMAL ROM_Block.inc FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL ROM_Block.cmp FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL ROM_Block.bsf FALSE
-- Retrieval info: GEN_FILE: TYPE_NORMAL ROM_Block_inst.vhd FALSE
-- Retrieval info: LIB_FILE: altera_mf

35
cs208-ca/vhdl/add_sub.vhd Executable file
View File

@@ -0,0 +1,35 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity add_sub is
port(
a : in std_logic_vector(31 downto 0);
b : in std_logic_vector(31 downto 0);
sub_mode : in std_logic;
carry : out std_logic;
zero : out std_logic;
r : out std_logic_vector(31 downto 0)
);
end add_sub;
architecture synth of add_sub is
signal bsub : std_logic_vector(31 downto 0);
signal temp : unsigned(32 downto 0);
signal addout : std_logic_vector(32 downto 0);
signal tempr : std_logic_vector(31 downto 0);
signal subvec : std_logic_vector(31 downto 0);
begin
subvec <= ((31 downto 1 => '0') & sub_mode);
bsub <= b xor (31 downto 0 => sub_mode);
temp <= unsigned('0' & a) + unsigned('0' & bsub)+ unsigned('0' & subvec);
addout <= std_logic_vector(temp);
tempr <= addout(31 downto 0);
carry <= addout(32);
zero <= '1' when unsigned(tempr) = 0 else '0';
r <= tempr;
end synth;

81
cs208-ca/vhdl/buttons.vhd Executable file
View File

@@ -0,0 +1,81 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity buttons is
port(
-- bus interface
clk : in std_logic;
reset_n : in std_logic;
cs : in std_logic;
read : in std_logic;
write : in std_logic;
address : in std_logic;
wrdata : in std_logic_vector(31 downto 0);
buttons : in std_logic_vector(3 downto 0);
-- irq : out std_logic;
rddata : out std_logic_vector(31 downto 0)
);
end buttons;
architecture synth of buttons is
constant REG_DATA : std_logic := '0';
constant REG_EDGE : std_logic := '1';
signal address_reg : std_logic;
signal read_reg : std_logic;
signal buttons_reg : std_logic_vector(3 downto 0);
signal edges : std_logic_vector(3 downto 0);
begin
--irq <= '0' when unsigned(edges) = 0 else '1';
-- address_reg & button_reg
process(clk, reset_n)
begin
if (reset_n = '0') then
address_reg <= '0';
read_reg <= '0';
buttons_reg <= (others => '1');
elsif (rising_edge(clk)) then
address_reg <= address;
read_reg <= read and cs;
buttons_reg <= buttons;
end if;
end process;
-- read
process(read_reg, address_reg, edges, buttons)
begin
rddata <= (others => 'Z');
if (read_reg = '1') then
rddata <= (others => '0');
case address_reg is
when REG_DATA =>
rddata(3 downto 0) <= buttons;
when REG_EDGE =>
rddata(3 downto 0) <= edges;
when others =>
end case;
end if;
end process;
-- edges
process(clk, reset_n)
begin
if (reset_n = '0') then
edges <= (others => '0');
elsif (rising_edge(clk)) then
-- edge detection
edges <= edges or (not buttons and buttons_reg);
-- clear edges
if (cs = '1' and write = '1') then
if (address = REG_EDGE) then
edges <= (others => '0');
end if;
end if;
end if;
end process;
end synth;

25
cs208-ca/vhdl/comparator.vhd Executable file
View File

@@ -0,0 +1,25 @@
library ieee;
use ieee.std_logic_1164.all;
entity comparator is
port(
a_31 : in std_logic;
b_31 : in std_logic;
diff_31 : in std_logic;
carry : in std_logic;
zero : in std_logic;
op : in std_logic_vector(2 downto 0);
r : out std_logic
);
end comparator;
architecture synth of comparator is
begin
r <= ((a_31 and (not(b_31))) or ((a_31 xnor b_31) and (diff_31 or zero))) when op = "001" else
((not(a_31) and b_31) or ((a_31 xnor b_31) and (not(diff_31 or zero)))) when op = "010" else
not(zero) when op = "011" else
(not(carry) or zero) when op = "101" else
(carry and not(zero)) when op = "110" else
zero;
end synth;

233
cs208-ca/vhdl/controller.vhd Executable file
View File

@@ -0,0 +1,233 @@
library ieee;
use ieee.std_logic_1164.all;
entity controller is
port(
clk : in std_logic;
reset_n : in std_logic;
-- instruction opcode
op : in std_logic_vector(5 downto 0);
opx : in std_logic_vector(5 downto 0);
-- activates branch condition
branch_op : out std_logic;
-- immediate value sign extention
imm_signed : out std_logic;
-- instruction register enable
ir_en : out std_logic;
-- PC control signals
pc_add_imm : out std_logic;
pc_en : out std_logic;
pc_sel_a : out std_logic;
pc_sel_imm : out std_logic;
-- register file enable
rf_wren : out std_logic;
-- multiplexers selections
sel_addr : out std_logic;
sel_b : out std_logic;
sel_mem : out std_logic;
sel_pc : out std_logic;
sel_ra : out std_logic;
sel_rC : out std_logic;
-- write memory output
read : out std_logic;
write : out std_logic;
-- alu op
op_alu : out std_logic_vector(5 downto 0)
);
end controller;
architecture synth of controller is
type state is (FETCH1, FETCH2, DECODE, R_OP, STORE, BREAK, LOAD1, I_OP, LOAD2, BRANCH, CALL,CALLR, JMP, JMPI, UI_OP, RI_OP);
signal s_cur : state;
signal s_next : state;
begin
--FSM masuta controls
fsm_ctrl : process(clk, reset_n) is
begin
if(reset_n = '0') then
s_cur <= FETCH1;
elsif(rising_edge(clk)) then
s_cur <= s_next;
end if;
end process;
--control states
s_next <= FETCH2 when s_cur = FETCH1 else
DECODE when s_cur = FETCH2 else
BREAK when s_cur = BREAK else
LOAD2 when s_cur = LOAD1 else
FETCH1 when (s_cur = LOAD2 or s_cur = STORE or
s_cur = R_OP or s_cur = I_OP or s_cur = RI_OP or s_cur = UI_OP or
s_cur = BRANCH or s_cur = CALL or s_cur = CALLR or s_cur = JMP or s_cur = JMPI) else
R_OP when (s_cur = DECODE and op = "111010" and (opx = "011011" or --srl
opx = "110001" or --add
opx = "111001" or --sub
opx = "001000" or --cmple
opx = "010000" or --cmpgt
opx = "000110" or --nor
opx = "001110" or --and
opx = "010110" or --or
opx = "011110" or --xnor
opx = "010011" or --sll
opx = "111011" or --sra
opx = "011000" or --cmpne
opx = "100000" or --cmpeq
opx = "101000" or --cmpleu
opx = "110000" or --cmpgtu
opx = "000011" or --rol
opx = "001011") --ror
) else
I_OP when (s_cur = DECODE and (op = "000100" or --addi
op = "001000" or --cmplei
op = "010000" or --cmpgti
op = "011000" or --cmpnei
op = "100000") --cmpeqi
) else
UI_OP when (s_cur = DECODE and (op = "001100" or --andi
op = "010100" or --ori
op = "011100" or --xnori
op = "101000" or --cmpleui
op = "110000") --cmpgtui
) else
RI_OP when (s_cur = DECODE and op = "111010" and (opx = "010010" or --slli
opx = "011010" or --srli
opx = "111010" or --srai
opx = "000010") --roli
) else
LOAD1 when (s_cur = DECODE and op = "010111") else --ldw
STORE when (s_cur = DECODE and op = "010101") else --stw
BRANCH when (s_cur = DECODE and (op = "000110" or --br
op = "001110" or --ble
op = "010110" or --bgt
op = "011110" or --bne
op = "100110" or --beq
op = "101110" or --bleu
op = "110110") --bgtu
) else
CALL when (s_cur = DECODE and op = "000000") else --call
CALLR when (s_cur = DECODE and opx = "011101") else --callr
JMP when (s_cur = DECODE and (opx = "001101" or --jmp
opx = "000101") --ret
) else
JMPI when (s_cur = DECODE and op = "000001") else --jmpi
BREAK when (s_cur = DECODE and op = "111010" and opx = "110100"); --break
--====== All state handlers =======--
pc_add_imm <= '1' when (s_cur = BRANCH) else '0';
pc_sel_a <= '1' when (s_cur = JMP or s_cur = CALLR) else'0';
pc_sel_imm <= '1' when (s_cur = CALL or s_cur = JMPI) else '0';
sel_pc <= '1' when (s_cur = CALL or s_cur = CALLR) else '0';
branch_op <= '1' when s_cur = BRANCH else '0';
pc_en <= '1' when (s_cur = FETCH2 or s_cur = CALL or s_cur = CALLR or s_cur = JMP or s_cur = JMPI) else '0';
read <= '1' when (s_cur = FETCH1 or
s_cur = LOAD1) else '0';
write <= '1' when (s_cur = STORE) else '0';
ir_en <= '1' when (s_cur = FETCH2) else '0';
rf_wren <= '1' when (s_cur = R_OP or
s_cur = RI_OP or
s_cur = I_OP or
s_cur = UI_OP or
s_cur = CALL or
s_cur = CALLR or
s_cur = LOAD2) else '0';
sel_rC <= '1' when (s_cur = R_OP or s_cur = RI_OP or s_cur = CALLR) else '0';
sel_b <= '1' when (s_cur = R_OP or s_cur = BRANCH) else '0';
sel_ra <= '1' when (s_cur = CALL or s_cur = CALLR) else '0';
sel_addr <= '1' when (s_cur = LOAD1 or
s_cur = STORE) else '0';
sel_mem <= '1' when s_cur = LOAD2 else '0';
imm_signed <= '1' when (s_cur = I_OP or
s_cur = LOAD1 or
s_cur = STORE) else '0';
-- Alu state
op_alu <= "000000" when (op = "000100" or --addi
op = "010111" or --ldw
op = "010101" --stw
) else --rA + (signed)imm
"000110" when (op = "111010" and opx = "110001" --add
) else --rA + rB
"001111" when (op = "111010" and opx = "111001" --sub
) else --rA - rB
"100001" when (op = "111010" and opx = "001110" --and
) else --rA & rB
"100001" when (op = "001100" --andi
) else --rA & (unsigned)imm
"100010" when (op = "111010" and opx = "010110" --or
) else --rA | rB
"101010" when (op = "010100" --ori
) else --rA | (unsigned)imm
"100011" when (op = "111010" and opx = "011110" --xnor
) else --rA xnor rB
"100011" when (op = "011100" --xnori
) else --rA xnor (unsigned)imm
"100000" when (op = "111010" and opx = "000110" --nor
) else --rA nor rB
"111011" when (op = "111010" and opx = "011010" --srli
) else --(unsigned)rA >> imm
"110011" when (op = "111010" and opx = "011011" --srl
) else --(unsigned)rA >> rB
"111010" when (op = "111010" and opx = "010010" --slli
) else --(unsigned)rA << imm
"110010" when (op = "111010" and opx = "010011" --sll
) else --(unsigned)rA << rB
"111111" when (op = "111010" and opx = "111010" --srai
) else --(signed)rA >> imm
"110111" when (op = "111010" and opx = "111011" --sra
) else --(signed)rA >> rB
"011001" when (op = "001110" or --ble
op = "001000" or --cmplei
(op = "111010" and opx = "001000") --cmple
) else -- rA <= rB , rA <= (signed)imm
"011010" when (op = "010110" or --bgt
op = "010000" or --cmpgti
(op = "111010" and opx = "010000") --cmpgt
) else -- rA > rB , rA > (signed)imm
"011011" when (op = "011110" or --bne
op = "011000" or --cmpnei
(op = "111010" and opx = "011000") --cmpne
) else -- rA != rB , rA != (signed)imm
"011100" when (op = "100110" or --beq
op = "000110" or --br
op = "100000" or --cmpeqi
(op = "111010" and opx = "100000") --cmpeq
) else --rA = rB , rA = (signed)imm
"011101" when (op = "101110" or --bleu
op = "101000" or --cmpleui
(op = "111010" and opx = "101000") --cmpleu
) else --(unsigned)rA <= (unsigned)rB , (unsigned)rA <= (unsigned)imm
"011110" when (op = "110110" or --bgtu
op = "110000" or --cmpgtui
(op = "111010" and opx = "110000") --cmpgtu
) else --(unsigned)rA > (unsigned)rB , (unsigned)rA > (unsigned)imm
"110000" when (op = "111010" and opx = "000011" --rol
) else --rA rol rB
"111000" when (op = "111010" and opx = "000010" --roli
) else --rA rol imm
"110001" when (op = "111010" and opx = "001011" --ror
) else --rA ror rB
"000000"; --DEFAULT
end synth;

233
cs208-ca/vhdl/controller.vhd.bak Executable file
View File

@@ -0,0 +1,233 @@
library ieee;
use ieee.std_logic_1164.all;
entity controller is
port(
clk : in std_logic;
reset_n : in std_logic;
-- instruction opcode
op : in std_logic_vector(5 downto 0);
opx : in std_logic_vector(5 downto 0);
-- activates branch condition
branch_op : out std_logic;
-- immediate value sign extention
imm_signed : out std_logic;
-- instruction register enable
ir_en : out std_logic;
-- PC control signals
pc_add_imm : out std_logic;
pc_en : out std_logic;
pc_sel_a : out std_logic;
pc_sel_imm : out std_logic;
-- register file enable
rf_wren : out std_logic;
-- multiplexers selections
sel_addr : out std_logic;
sel_b : out std_logic;
sel_mem : out std_logic;
sel_pc : out std_logic;
sel_ra : out std_logic;
sel_rC : out std_logic;
-- write memory output
read : out std_logic;
write : out std_logic;
-- alu op
op_alu : out std_logic_vector(5 downto 0)
);
end controller;
architecture synth of controller is
type state is (FETCH1, FETCH2, DECODE, R_OP, STORE, BREAK, LOAD1, I_OP, LOAD2, BRANCH, CALL,CALLR, JMP, JMPI, UI_OP, RI_OP);
signal s_cur : state;
signal s_next : state;
begin
--FSM masuta controls
fsm_ctrl : process(clk, reset_n) is
begin
if(reset_n = '0') then
s_cur <= FETCH1;
elsif(rising_edge(clk)) then
s_cur <= s_next;
end if;
end process;
--control states
s_next <= FETCH2 when s_cur = FETCH1 else
DECODE when s_cur = FETCH2 else
BREAK when s_cur = BREAK else
LOAD2 when s_cur = LOAD1 else
FETCH1 when (s_cur = LOAD2 or s_cur = STORE or
s_cur = R_OP or s_cur = I_OP or s_cur = RI_OP or s_cur = UI_OP or
s_cur = BRANCH or s_cur = CALL or s_cur = CALLR or s_cur = JMP or s_cur = JMPI) else
R_OP when (s_cur = DECODE and op = "111010" and (opx = "011011" or --srl
opx = "110001" or --add
opx = "111001" or --sub
opx = "001000" or --cmple
opx = "010000" or --cmpgt
opx = "000110" or --nor
opx = "001110" or --and
opx = "010110" or --or
opx = "011110" or --xnor
opx = "010011" or --sll
opx = "111011" or --sra
opx = "011000" or --cmpne
opx = "100000" or --cmpeq
opx = "101000" or --cmpleu
opx = "110000" or --cmpgtu
opx = "000011" or --rol
opx = "001011") --ror
) else
I_OP when (s_cur = DECODE and (op = "000100" or --addi
op = "001000" or --cmplei
op = "010000" or --cmpgti
op = "011000" or --cmpnei
op = "100000") --cmpeqi
-- op = "001010") --????????????????????????????????????????
) else
UI_OP when (s_cur = DECODE and (op = "001100" or --andi
op = "010100" or --ori
op = "011100" or --xnori
op = "101000" or --cmpleui
op = "110000") --cmpgtui
) else
RI_OP when (s_cur = DECODE and op = "111010" and (opx = "010010" or --slli
opx = "011010" or --srli
opx = "111010" or --srai
opx = "000010") --roli
) else
LOAD1 when (s_cur = DECODE and op = "010111") else --ldw
STORE when (s_cur = DECODE and op = "010101") else --stw
BRANCH when (s_cur = DECODE and (op = "000110" or --br
op = "001110" or --ble
op = "010110" or --bgt
op = "011110" or --bne
op = "100110" or --beq
op = "101110" or --bleu
op = "110110") --bgtu
) else
CALL when (s_cur = DECODE and op = "000000") else --call
CALLR when (s_cur = DECODE and opx = "011101") else --callr
JMP when (s_cur = DECODE and (opx = "001101" or --jmp
opx = "000101") --ret
) else
JMPI when (s_cur = DECODE and op = "000001") else --jmpi
BREAK when (s_cur = DECODE and op = "111010" and opx = "110100"); --break
--====== All state handlers =======--
pc_add_imm <= '1' when (s_cur = BRANCH) else '0';
pc_sel_a <= '1' when (s_cur = JMP or s_cur = CALLR) else'0';
pc_sel_imm <= '1' when (s_cur = CALL or s_cur = JMPI) else '0';
sel_pc <= '1' when s_cur = CALL or s_cur = CALLR else '0';
branch_op <= '1' when s_cur = BRANCH else '0';
pc_en <= '1' when (s_cur = FETCH1 or s_cur = CALL or s_cur = CALLR or s_cur = JMP or s_cur = JMPI) else '0';
read <= '1' when (s_cur = FETCH1 or
s_cur = LOAD1) else '0';
write <= '1' when (s_cur = STORE) else '0';
ir_en <= '1' when (s_cur = FETCH2) else '0';
rf_wren <= '1' when (s_cur = R_OP or
s_cur = RI_OP or
s_cur = I_OP or
s_cur = UI_OP or
s_cur = CALL or
s_cur = CALLR or
s_cur = LOAD2) else '0';
sel_rC <= '1' when (s_cur = R_OP or s_cur = RI_OP or s_cur = CALLR) else '0';
sel_b <= '1' when (s_cur = R_OP or s_cur = BRANCH) else '0';
sel_ra <= '1' when (s_cur = CALL or s_cur = CALLR) else '0';
sel_addr <= '1' when (s_cur = LOAD1 or
s_cur = STORE) else '0';
sel_mem <= '1' when s_cur = LOAD2 else '0';
imm_signed <= '1' when (s_cur = I_OP or
s_cur = LOAD1 or
s_cur = STORE) else '0';
-- Alu state
op_alu <= "000000" when (op = "000100" or --addi
op = "010111" or --ldw
op = "010101" --stw
) else --rA + (signed)imm
"000110" when (op = "111010" and opx = "110001" --add
) else --rA + rB
"001111" when (op = "111010" and opx = "111001" --sub
) else --rA - rB
"100001" when (op = "111010" and opx = "001110" --and
) else --rA & rB
"100001" when (op = "001100" --andi
) else --rA & (unsigned)imm
"100010" when (op = "111010" and opx = "010110" --or
) else --rA | rB
"101010" when (op = "010100" --ori
) else --rA | (unsigned)imm
"100011" when (op = "111010" and opx = "011110" --xnor
) else --rA xnor rB
"100011" when (op = "011100" --xnori
) else --rA xnor (unsigned)imm
"100000" when (op = "111010" and opx = "000110" --nor
) else --rA nor rB
"111011" when (op = "111010" and opx = "011010" --srli
) else --(unsigned)rA >> imm
"110011" when (op = "111010" and opx = "011011" --srl
) else --(unsigned)rA >> rB
"111010" when (op = "111010" and opx = "010010" --slli
) else --(unsigned)rA << imm
"110010" when (op = "111010" and opx = "010011" --sll
) else --(unsigned)rA << rB
"111111" when (op = "111010" and opx = "111010" --srai
) else --(signed)rA >> imm
"110111" when (op = "111010" and opx = "111011" --sra
) else --(signed)rA >> rB
"011001" when (op = "001110" or --ble
op = "001000" or --cmplei
(op = "111010" and opx = "001000") --cmple
) else -- rA <= rB , rA <= (signed)imm
"011010" when (op = "010110" or --bgt
op = "010000" or --cmpgti
(op = "111010" and opx = "010000") --cmpgt
) else -- rA > rB , rA > (signed)imm
"011011" when (op = "011110" or --bne
op = "011000" or --cmpnei
(op = "111010" and opx = "011000") --cmpne
) else -- rA != rB , rA != (signed)imm
"011100" when (op = "100110" or --beq
op = "100000" or --cmpeqi
(op = "111010" and opx = "100000") --cmpeq
) else --rA = rB , rA = (signed)imm
"011101" when (op = "101110" or --bleu
op = "101000" or --cmpleui
(op = "111010" and opx = "101000") --cmpleu
) else --(unsigned)rA <= (unsigned)rB , (unsigned)rA <= (unsigned)imm
"011110" when (op = "110110" or --bgtu
op = "110000" or --cmpgtui
(op = "111010" and opx = "110000") --cmpgtu
) else --(unsigned)rA > (unsigned)rB , (unsigned)rA > (unsigned)imm
"110000" when (op = "111010" and opx = "000011" --rol
) else --rA rol rB
"111000" when (op = "111010" and opx = "000010" --roli
) else --rA rol imm
"110001" when (op = "111010" and opx = "001011" --ror
) else --rA ror rB
"000000"; --DEFAULT
end synth;

45
cs208-ca/vhdl/decoder.vhd Executable file
View File

@@ -0,0 +1,45 @@
library ieee;
use ieee.std_logic_1164.all;
entity decoder is
port(
address : in std_logic_vector(15 downto 0);
cs_LEDS : out std_logic;
cs_RAM : out std_logic;
cs_ROM : out std_logic;
cs_buttons : out std_logic
);
end decoder;
architecture synth of decoder is
begin
process(address)
begin
if(address <= X"0FFC") then
cs_ROM <='1';
cs_RAM <= '0';
cs_LEDS <= '0';
cs_buttons <= '0';
elsif(address <= X"1FFC") then
cs_ROM <='0';
cs_RAM <= '1';
cs_LEDS <= '0';
cs_buttons <= '0';
elsif(address <= X"200C") then
cs_ROM <='0';
cs_RAM <= '0';
cs_LEDS <= '1';
cs_buttons <= '0';
elsif(address >= x"2030" and address < x"2034") then
cs_ROM <='0';
cs_RAM <= '0';
cs_LEDS <= '0';
cs_buttons <= '1';
else
cs_ROM <='0';
cs_RAM <= '0';
cs_LEDS <= '0';
cs_buttons <= '0';
end if;
end process;
end synth;

19
cs208-ca/vhdl/extend.vhd Executable file
View File

@@ -0,0 +1,19 @@
library ieee;
use ieee.std_logic_1164.all;
entity extend is
port(
imm16 : in std_logic_vector(15 downto 0);
signed : in std_logic;
imm32 : out std_logic_vector(31 downto 0)
);
end extend;
architecture synth of extend is
begin
imm32 <= (15 downto 0 => '0') & imm16 when signed = '0' else
(15 downto 0 => imm16(15)) & imm16(15 downto 0);
end synth;

19
cs208-ca/vhdl/logic_unit.vhd Executable file
View File

@@ -0,0 +1,19 @@
library ieee;
use ieee.std_logic_1164.all;
entity logic_unit is
port(
a : in std_logic_vector(31 downto 0);
b : in std_logic_vector(31 downto 0);
op : in std_logic_vector(1 downto 0);
r : out std_logic_vector(31 downto 0)
);
end logic_unit;
architecture synth of logic_unit is
begin
r <= a nor b when op = "00" else
a and b when op = "01" else
a or b when op = "10" else
a xnor b;
end synth;

22
cs208-ca/vhdl/multiplexer.vhd Executable file
View File

@@ -0,0 +1,22 @@
library ieee;
use ieee.std_logic_1164.all;
entity multiplexer is
port(
i0 : in std_logic_vector(31 downto 0);
i1 : in std_logic_vector(31 downto 0);
i2 : in std_logic_vector(31 downto 0);
i3 : in std_logic_vector(31 downto 0);
sel : in std_logic_vector(1 downto 0);
o : out std_logic_vector(31 downto 0)
);
end multiplexer;
architecture synth of multiplexer is
begin
o <= i0 when sel = "00" else
i1 when sel = "01" else
i2 when sel = "10" else
i3 when sel = "11" else
i0;
end synth;

19
cs208-ca/vhdl/mux2x16.vhd Executable file
View File

@@ -0,0 +1,19 @@
library ieee;
use ieee.std_logic_1164.all;
entity mux2x16 is
port(
i0 : in std_logic_vector(15 downto 0);
i1 : in std_logic_vector(15 downto 0);
sel : in std_logic;
o : out std_logic_vector(15 downto 0)
);
end mux2x16;
architecture synth of mux2x16 is
begin
o <= i0 when sel = '0' else
i1;
end synth;

19
cs208-ca/vhdl/mux2x32.vhd Executable file
View File

@@ -0,0 +1,19 @@
library ieee;
use ieee.std_logic_1164.all;
entity mux2x32 is
port(
i0 : in std_logic_vector(31 downto 0);
i1 : in std_logic_vector(31 downto 0);
sel : in std_logic;
o : out std_logic_vector(31 downto 0)
);
end mux2x32;
architecture synth of mux2x32 is
begin
o <= i0 when sel = '0' else
i1;
end synth;

19
cs208-ca/vhdl/mux2x5.vhd Executable file
View File

@@ -0,0 +1,19 @@
library ieee;
use ieee.std_logic_1164.all;
entity mux2x5 is
port(
i0 : in std_logic_vector(4 downto 0);
i1 : in std_logic_vector(4 downto 0);
sel : in std_logic;
o : out std_logic_vector(4 downto 0)
);
end mux2x5;
architecture synth of mux2x5 is
begin
o <= i0 when sel = '0' else
i1;
end synth;

40
cs208-ca/vhdl/register_file.vhd Executable file
View File

@@ -0,0 +1,40 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity register_file is
port(
clk : in std_logic;
aa : in std_logic_vector(4 downto 0);
ab : in std_logic_vector(4 downto 0);
aw : in std_logic_vector(4 downto 0);
wren : in std_logic;
wrdata : in std_logic_vector(31 downto 0);
a : out std_logic_vector(31 downto 0);
b : out std_logic_vector(31 downto 0)
);
end register_file;
architecture synth of register_file is
type reg_type is array(0 to 31) of std_logic_vector(31 downto 0);
signal reg : reg_type := (others => (others => '0'));
begin
a <= reg(to_integer(unsigned(aa)));
b <= reg(to_integer(unsigned(ab)));
write: process(clk) is
begin
if(rising_edge(clk)) then
if(wren = '1') then
reg(to_integer(unsigned(aw))) <= wrdata;
end if;
reg(0) <= (31 downto 0 => '0');
end if;
end process write;
end synth;

View File

@@ -0,0 +1,39 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity register_file is
port(
clk : in std_logic;
aa : in std_logic_vector(4 downto 0);
ab : in std_logic_vector(4 downto 0);
aw : in std_logic_vector(4 downto 0);
wren : in std_logic;
wrdata : in std_logic_vector(31 downto 0);
a : out std_logic_vector(31 downto 0);
b : out std_logic_vector(31 downto 0)
);
end register_file;
architecture synth of register_file is
type reg_type is array(0 to 31) of std_logic_vector(31 downto 0);
signal reg : reg_type := (others => (others => '0'));
begin
a <= reg(to_integer(unsigned(aa)));
b <= reg(to_integer(unsigned(ab)));
write: process(clk) is
begin
if(rising_edge(clk)) then
if(wren = '1') then
reg(to_integer(unsigned(aw))) <= wrdata;
reg(0) <= (31 downto 0 => '0');
end if;
end if;
end process write;
end synth;

277
cs208-ca/vhdl/rgb_led96.vhd Executable file
View File

@@ -0,0 +1,277 @@
-- RGB LEDs x96 simple interface
-- author: xavier.jimenez@epfl.ch
-- file: rgb_led96.vhd
-- A simple interface to control 96 rgb leds.
-- Monochrome version: every LED will have the same color.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;
package pack is
function f_ceil_log2 (constant n : natural)
return natural;
end pack;
package body pack is
-- computes ceil(log2(N))
function f_ceil_log2 (constant n : natural) return natural is
variable n_v : natural;
variable ret : natural;
begin
assert n > 0
report "pack.f_ceil_log2(n): input n should be greater than 0."
severity error;
ret := 0;
n_v := 2*n-1;
while n_v > 1 loop
ret := ret + 1;
n_v := n_v / 2;
end loop;
return ret;
end f_ceil_log2;
end pack;
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
USE ieee.std_logic_arith.all;
USE work.pack.all;
entity rgb_led96 is
generic (
-- input clock frequency in Hz
CLK_FREQ : natural := 50000000;
-- desired frame rate in Hz
FRAME_RATE : natural := 100;
DEFAULT_COLOR : std_logic_vector(23 downto 0) := X"0000FF"
);
port (
-- global
clk : in std_logic;
reset : in std_logic;
-- LEDs
LEDs : in std_logic_vector(95 downto 0);
-- a global color, 8 bits per channel, red by default
color : in std_logic_vector(23 downto 0) := DEFAULT_COLOR; --X"0000FF";
-- RGB LEDS matrix
LED_SelC_n : out std_logic_vector(11 downto 0);
LED_Sel_R : out std_logic_vector(7 downto 0);
LED_Sel_G : out std_logic_vector(7 downto 0);
LED_Sel_B : out std_logic_vector(7 downto 0);
LED_reset : out std_logic
);
end entity;
-- Architecture Body
architecture arch of rgb_led96 is
constant C_ROWS : natural := 8;
constant C_COLUMNS : natural := 12;
constant C_PWM_BITS : natural := 15;
-- time spent reseting a line (fixed to 1us)
constant C_PERIOD_RST : natural := CLK_FREQ/1000000;
-- maximum time period per line to satisfy frame rate
constant C_MAX_PERIOD : natural := CLK_FREQ/FRAME_RATE/C_COLUMNS - 1;
-- pwm cycle count during a display phase.
-- We fix the pwm on 2**15 clock cycles and want a display phase aligned to it
-- total line refresh is made of: 2 transitional cycles, a reset phase and the display phase.
constant C_PWM_CYCLES : natural := (C_MAX_PERIOD-C_PERIOD_RST-2)/(2**C_PWM_BITS);
-- display period
constant C_DISPLAY_PERIOD : natural := (2**C_PWM_BITS)*C_PWM_CYCLES;
-- we get the bitwidth of the period counter
constant C_PERIOD_WIDTH : natural := f_ceil_log2(C_DISPLAY_PERIOD);
type t_matrix is array(0 to 11) of std_logic_vector(7 downto 0);
signal s_led_matrix : t_matrix;
-- a register to store the pwm threshold for the one value and each channel
signal reg_pwm_thres : std_logic_vector(3*16-1 downto 0);
-- period counter
signal reg_period_cnt : std_logic_vector(C_PERIOD_WIDTH-1 downto 0);
-- current col index
signal reg_col_cnt : std_logic_vector(3 downto 0);
-- current col vector (single bit active on a 24-bit vector)
signal reg_sel_col : std_logic_vector(11 downto 0);
-- gamma 2.2 array to translate RGB to pwm duty cycles
type t_array16 is array (0 to 255) of std_logic_vector(15 downto 0);
signal gamma_table : t_array16 :=
( X"0000", X"0001", X"0002", X"0003", X"0004", X"0005", X"0006", X"0007", X"0008", X"0009", X"000A", X"000B", X"000C", X"000D", X"000E", X"000F", X"0010"
, X"0011", X"0012", X"0013", X"0014", X"0015", X"0016", X"0017", X"0018", X"0019", X"001B", X"001D", X"0020", X"0022", X"0025", X"0028", X"002B"
, X"002E", X"0031", X"0034", X"0037", X"003B", X"003E", X"0042", X"0046", X"0049", X"004D", X"0052", X"0056", X"005A", X"005F", X"0063", X"0068"
, X"006D", X"0072", X"0077", X"007C", X"0081", X"0087", X"008C", X"0092", X"0098", X"009E", X"00A4", X"00AA", X"00B0", X"00B6", X"00BD", X"00C4"
, X"00CA", X"00D1", X"00D8", X"00E0", X"00E7", X"00EE", X"00F6", X"00FE", X"0105", X"010D", X"0115", X"011E", X"0126", X"012E", X"0137", X"0140"
, X"0149", X"0152", X"015B", X"0164", X"016D", X"0177", X"0181", X"018A", X"0194", X"019E", X"01A8", X"01B3", X"01BD", X"01C8", X"01D3", X"01DD"
, X"01E9", X"01F4", X"01FF", X"020A", X"0216", X"0222", X"022D", X"0239", X"0246", X"0252", X"025E", X"026B", X"0277", X"0284", X"0291", X"029E"
, X"02AC", X"02B9", X"02C6", X"02D4", X"02E2", X"02F0", X"02FE", X"030C", X"031B", X"0329", X"0338", X"0346", X"0355", X"0365", X"0374", X"0383"
, X"0393", X"03A2", X"03B2", X"03C2", X"03D2", X"03E2", X"03F3", X"0403", X"0414", X"0425", X"0436", X"0447", X"0458", X"046A", X"047B", X"048D"
, X"049F", X"04B1", X"04C3", X"04D6", X"04E8", X"04FB", X"050D", X"0520", X"0533", X"0547", X"055A", X"056D", X"0581", X"0595", X"05A9", X"05BD"
, X"05D1", X"05E6", X"05FA", X"060F", X"0624", X"0639", X"064E", X"0664", X"0679", X"068F", X"06A4", X"06BA", X"06D1", X"06E7", X"06FD", X"0714"
, X"072A", X"0741", X"0758", X"0770", X"0787", X"079E", X"07B6", X"07CE", X"07E6", X"07FE", X"0816", X"082F", X"0847", X"0860", X"0879", X"0892"
, X"08AB", X"08C5", X"08DE", X"08F8", X"0912", X"092C", X"0946", X"0960", X"097B", X"0995", X"09B0", X"09CB", X"09E6", X"0A01", X"0A1D", X"0A38"
, X"0A54", X"0A70", X"0A8C", X"0AA8", X"0AC5", X"0AE1", X"0AFE", X"0B1B", X"0B38", X"0B55", X"0B73", X"0B90", X"0BAE", X"0BCC", X"0BEA", X"0C08"
, X"0C26", X"0C45", X"0C63", X"0C82", X"0CA1", X"0CC0", X"0CDF", X"0CFF", X"0D1F", X"0D3E", X"0D5E", X"0D7E", X"0D9F", X"0DBF", X"0DE0", X"0E01"
, X"0E22", X"0E43", X"0E64", X"0E85", X"0EA7", X"0EC9", X"0EEB", X"0F0D", X"0F2F", X"0F51", X"0F74", X"0F97", X"0FBA", X"0FDD", X"1000");
signal s_gamma_addr : std_logic_vector(7 downto 0);
signal reg_gamma_data : std_logic_vector(15 downto 0);
-- FSM
type t_state is (TRANS1, RST, TRANS2, DISPLAY);
signal state, next_state : t_state;
begin
-- led matrix mapping
g_matrix_i : for i in 0 to 11 generate
s_led_matrix(i) <= LEDs((i+1)*8-1 downto i*8);
end generate;
-- col activation
LED_SelC_n <= not reg_sel_col when state = DISPLAY else (others => '1');
-- row activation
process (reg_period_cnt, state, reg_pwm_thres, s_led_matrix, reg_col_cnt)
variable v_pwm : std_logic_vector(C_PWM_BITS-1 downto 0);
begin
-- by default, each channel at 0
LED_Sel_R <= (others=>'0');
LED_Sel_G <= (others=>'0');
LED_Sel_B <= (others=>'0');
v_pwm := reg_period_cnt(C_PWM_BITS-1 downto 0);
if (state = DISPLAY) then
if (reg_pwm_thres(46 downto 32) > v_pwm) then
LED_Sel_R <= s_led_matrix(conv_integer(reg_col_cnt));
end if;
-- green
if (reg_pwm_thres(30 downto 16) > v_pwm) then
LED_Sel_G <= s_led_matrix(conv_integer(reg_col_cnt));
end if;
-- blue
if (reg_pwm_thres(14 downto 0) > v_pwm) then
LED_Sel_B <= s_led_matrix(conv_integer(reg_col_cnt));
end if;
end if;
end process;
-- combinatorial gamma address
process (color, state, reg_period_cnt)
begin
-- the address to the gamma table
-- by default we point on the first channel
s_gamma_addr <= color(7 downto 0); -- (blue)
-- then during the first two cycle of the reset phase, we switch to the other two
if (state = RST) then
if (reg_period_cnt <= 1) then
if (reg_period_cnt(0) = '0') then
s_gamma_addr <= color(15 downto 8); -- (green)
else
s_gamma_addr <= color(23 downto 16); -- (red)
end if;
end if;
end if;
end process;
-- loading the pwm threshold reference for the 1s during the reset state.
process (clk) -- no need for reset
begin
if (rising_edge(clk)) then
reg_gamma_data <= gamma_table(conv_integer(s_gamma_addr));
-- the reg column
if (state = RST) then
if (reg_period_cnt <= 2) then
-- for green and blue the value must be doubled
case reg_period_cnt(1 downto 0) is
when "00" | "01" =>
-- (blue and green delayed by 1 cycle (reading gamma has 1-cycle latency))
reg_pwm_thres <= reg_gamma_data(14 downto 0) & '0' & reg_pwm_thres(3*16-1 downto 16);
when others =>
reg_pwm_thres <= reg_gamma_data & reg_pwm_thres(3*16-1 downto 16);
end case;
end if;
end if;
end if;
end process;
-- registers and counters
process (reset, clk)
begin
if (reset = '1') then
state <= TRANS1;
reg_period_cnt <= (others => '0');
reg_col_cnt <= (others => '0');
reg_sel_col <= (0 => '1', others => '0');
elsif rising_edge(clk) then
state <= next_state;
-- period counter
case state is
when TRANS1 | TRANS2 =>
reg_period_cnt <= (others => '0');
when RST | DISPLAY =>
reg_period_cnt <= reg_period_cnt + 1;
when others =>
end case;
-- new column
if (state = TRANS1) then
-- we activate the next column
reg_sel_col <= reg_sel_col(10 downto 0) & reg_sel_col(11);
-- we update the column index after a reset, during trans2
if (reg_col_cnt = 11) then
reg_col_cnt <= (others => '0');
else
reg_col_cnt <= reg_col_cnt + 1;
end if;
end if;
end if;
end process;
-- Simple state machine to switch between reset and display periods.
-- Between each transition we deactivate every signal for 1 cycle to
-- ensure that the RGB_reset signal cannot be activated along with a
-- column selection (shortcut)
process (state, reg_period_cnt)
begin
LED_reset <= '0';
next_state <= state;
case state is
when TRANS1 =>
next_state <= RST;
when RST =>
LED_reset <= '1';
if (reg_period_cnt = C_PERIOD_RST-1) then
next_state <= TRANS2;
end if;
when TRANS2 =>
next_state <= DISPLAY;
when DISPLAY =>
if (reg_period_cnt = C_DISPLAY_PERIOD-1) then
next_state <= TRANS1;
end if;
when others =>
end case;
end process;
end architecture;

177
cs208-ca/vhdl/shift_unit.vhd Executable file
View File

@@ -0,0 +1,177 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity shift_unit is
port(
a : in std_logic_vector(31 downto 0);
b : in std_logic_vector(4 downto 0);
op : in std_logic_vector(2 downto 0);
r : out std_logic_vector(31 downto 0)
);
end shift_unit;
architecture synth of shift_unit is
--signal sb : std_logic_vector(4 downto 0);
signal sl : std_logic_vector(31 downto 0);
signal sr : std_logic_vector(31 downto 0);
signal sar : std_logic_vector(31 downto 0);
begin
shift_l : process(a,b,op)
variable v : std_logic_vector(31 downto 0);
begin
--if(op(0) = '0') then
-- sb <= b;
--else
-- sb <= std_logic_vector(unsigned(not b)+1);
--end if;
v := a;
-- shift by 1
if(b(0) = '1')then
if(op(1)='1') then
v := v(30 downto 0) & '0';
else
v := v(30 downto 0) & v(31);
end if;
end if;
-- shift by 2
if(b(1) = '1') then
if(op(1)='1') then
v := v(29 downto 0) & (1 downto 0 => '0');
else
v := v(29 downto 0) & v(31 downto 30);
end if;
end if;
-- shift by 4
if (b(2) = '1') then
if(op(1)='1') then
v := v(27 downto 0) & (3 downto 0 => '0');
else
v := v(27 downto 0) & v(31 downto 28);
end if;
end if;
-- shift by 8
if(b(3) = '1') then
if(op(1)='1') then
v := v(23 downto 0) & (7 downto 0 => '0');
else
v := v(23 downto 0) & v(31 downto 24);
end if;
end if;
-- shift by 16
if(b(4) = '1') then
if(op(1)='1') then
v := v(15 downto 0) & (15 downto 0 => '0');
else
v := v(15 downto 0) & v(31 downto 16);
end if;
end if;
sl <= v;
end process;
shift_r : process(a,b,op)
variable v : std_logic_vector(31 downto 0);
begin
--if(op(0) = '0') then
-- sb <= b;
--else
-- sb <= std_logic_vector(unsigned(not b)+1);
--end if;
v := a;
-- shift by 1
if(b(0) = '1')then
if(op(1)='1') then
v := '0' & v(31 downto 1);
else
v := v(1) & v(31 downto 1);
end if;
end if;
-- shift by 2
if(b(1) = '1') then
if(op(1)='1') then
v := (1 downto 0 => '0') & v(31 downto 2);
else
v := v(1 downto 0) & v(31 downto 2);
end if;
end if;
-- shift by 4
if (b(2) = '1') then
if(op(1)='1') then
v := (3 downto 0 => '0') & v(31 downto 4);
else
v := v(3 downto 0) & v(31 downto 4);
end if;
end if;
-- shift by 8
if(b(3) = '1') then
if(op(1)='1') then
v := (7 downto 0 => '0') & v(31 downto 8);
else
v := v(7 downto 0) & v(31 downto 8);
end if;
end if;
-- shift by 16
if(b(4) = '1') then
if(op(1)='1') then
v := (15 downto 0 => '0') & v(31 downto 16);
else
v := v(15 downto 0) & v(31 downto 16);
end if;
end if;
sr <= v;
end process;
shift_ar : process(a,b,op)
variable v : std_logic_vector(31 downto 0);
begin
--if(op(0) = '0') then
-- sb <= b;
--else
-- sb <= std_logic_vector(unsigned(not b)+1);
--end if;
v := a;
-- shift by 1
if(b(0) = '1')then
v := v(31) & (v(31) & v(30 downto 1));
end if;
-- shift by 2
if(b(1) = '1') then
v := v(31) & ((1 downto 0 => v(31)) & v(30 downto 2));
end if;
-- shift by 4
if (b(2) = '1') then
v := v(31) & ((3 downto 0 => v(31)) & v(30 downto 4));
end if;
-- shift by 8
if(b(3) = '1') then
v := v(31) & ((7 downto 0 => v(31)) & v(30 downto 8));
end if;
-- shift by 16
if(b(4) = '1') then
v := v(31) & ((15 downto 0 => v(31)) & v(30 downto 16));
end if;
sar <= v;
end process;
r<= sar when op = "111" else
sl when op(0)='0' else
sr;
end synth;