OpenCores
URL https://opencores.org/ocsvn/cowgirl/cowgirl/trunk

Subversion Repositories cowgirl

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 2 to Rev 3
    Reverse comparison

Rev 2 → Rev 3

/tags/start/prog_rom.vhdl
0,0 → 1,53
library ieee;
use ieee.std_logic_1164.all;
 
entity prog_rom is port (
input: in std_logic_vector(15 downto 0);
output: out std_logic_vector(15 downto 0)
);
end;
 
architecture rom_arch of prog_rom is
begin
process(input)
begin
case input is
when "0000000000000000" => -- these are adds because otherwise
output <= "0010000000000000"; -- it'll never get out of idle
when "0000000000000001" =>
output <= "0010000000000000";
when "0000000000000010" =>
output <= "0100000000001100"; --lli 6
when "0000000000000011" =>
output <= "0100000000000001"; -- lui 0
when "0000000000000100" =>
output <= "0100001000000100"; -- lli 2
when "0000000000000101" =>
output <= "0100001000000001"; -- lui 0
when "0000000000000110" =>
output <= "0010010000001000"; -- add r2 <- r0 + r1
--when "0000000000001000" =>
--output <= "0011000001010011";
--when "0000000000001001" =>
--output <= "0011000001010100";
--when "0000000000001010" =>
--output <= "0011000001010101";
--when "0000000000001011" =>
--output <= "1000000001000000";
--when "0000000000001100" =>
--output <= "1001000001000000";
--when "0000000000001101" =>
--output <= "1010000001000000";
--when "0000000000001110" =>
--output <= "1010000001000001";
--when "0000000000001111" =>
--output <= "0101000000000000";
--when "0000000000010000" =>
--output <= "0101000000000001";
--when "0000000000010001" =>
--output <= "0101000000000010";
when others =>
output <= "1111000000000000";
end case;
end process;
end;
/tags/start/register.vhdl
0,0 → 1,32
-- 10/24/2005
-- 16 bit register
 
library ieee;
use ieee.std_logic_1164.all;
 
entity reg is port(
d : in std_logic_vector(15 downto 0);
clk : in std_logic;
wr_en: in std_logic;
q : out std_logic_vector(15 downto 0)
);
end reg;
 
architecture reg_arch of reg is
 
signal temp_q : std_logic_vector(15 downto 0) := x"0000";
begin
process(clk, wr_en, d)
begin
if (clk'event and clk='1') then
if wr_en = '1' then
temp_q <= d;
end if;
end if;
end process;
 
-- concurrent assignment
q <= temp_q;
end reg_arch;
/tags/start/shifter.vhdl
0,0 → 1,32
-- this is totally unimplemented becasue I don't feel like
-- doing it right now => .
 
library ieee;
use ieee.std_logic_1164.all;
 
entity shifter is
port (
n_shift : in std_logic_vector(7 downto 0); -- number of bits to shift
sh_type : in std_logic_vector(1 downto 0); -- which type of shift?
data : in std_logic_vector(15 downto 0); -- input data
o : out std_logic_vector(15 downto 0)); -- shifted data
 
end shifter;
 
architecture s_arch of shifter is
 
begin -- s_arch
 
sh_logic:process(sh_type)
begin
case sh_type is
when "00" => -- left, logical
o <= "0000000000000000";
when others => null;
end case;
end process sh_logic;
 
end s_arch;
/tags/start/cowgirl.vhdl
0,0 → 1,113
-- here's the whole thing
 
-- on 22 mar i did something strange. i took the pc off the clock and made it
-- transition on the signal next_instr from the control unit. that way, the
-- states will get the correct instruction
 
library ieee;
use ieee.std_logic_1164.all;
 
entity cowgirl is
port (
clk : in std_logic; -- system clock
reset : in std_logic; -- system reset
to_ram : out std_logic_vector(15 downto 0)); -- write to RAM
end cowgirl;
 
architecture cowgirl_arch of cowgirl is
component alu
port (
a : in std_logic_vector(15 downto 0);
b : in std_logic_vector(15 downto 0);
a_or_l : in std_logic;
op : in std_logic_vector(2 downto 0);
o : out std_logic_vector(15 downto 0));
end component;
 
component pc
port (
reset : in std_logic;
clk : in std_logic;
load : in std_logic;
d : in std_logic_vector(15 downto 0);
c : out std_logic_vector(15 downto 0));
end component;
 
component registers
port (
d : in std_logic_vector(15 downto 0);
clk : in std_logic;
addr_a : in std_logic_vector(2 downto 0);
addr_b : in std_logic_vector(2 downto 0);
wr_en : in std_logic;
a_o : out std_logic_vector(15 downto 0);
b_o : out std_logic_vector(15 downto 0));
end component;
 
component shifter
port (
n_shift : in std_logic_vector(7 downto 0);
sh_type : in std_logic_vector(1 downto 0);
data : in std_logic_vector(15 downto 0);
o : out std_logic_vector(15 downto 0));
end component;
 
component control
port (
instr : in std_logic_vector(15 downto 0);
clk : in std_logic;
reset : in std_logic;
mem_ready : in std_logic;
a_or_l : out std_logic;
op : out std_logic_vector(2 downto 0);
addr_a : out std_logic_vector(2 downto 0);
addr_b : out std_logic_vector(2 downto 0);
reg_addr : out std_logic_vector(2 downto 0);
to_regs : out std_logic_vector(15 downto 0);
to_pc : out std_logic_vector(15 downto 0);
load_pc : out std_logic;
reg_wr : out std_logic;
alu_or_imm: out std_logic;
next_instr: out std_logic;
curr_state: out std_logic_vector(15 downto 0));
end component;
 
component mux_2_1
port (
a : in std_logic_vector(15 downto 0);
b : in std_logic_vector(15 downto 0);
sel : in std_logic;
o : out std_logic_vector(15 downto 0));
end component;
 
component prog_rom
port (
input : in std_logic_vector(15 downto 0);
output : out std_logic_vector(15 downto 0));
end component;
 
-- here are my internal signals
signal reg_a_out, reg_b_out, alu_out, pc_to_rom, rom_out, immediate, reg_val : std_logic_vector(15 downto 0);
signal control_to_pc, curr_state : std_logic_vector(15 downto 0);
signal address_a, address_b, alu_opcode, reg_wr_addr : std_logic_vector(2 downto 0);
signal write_regs, a_or_l, load_pc, mem_ready, alu_or_imm, pc_clock : std_logic;
 
begin -- cowgirl_arch
 
regs: registers
port map (d => reg_val, clk => clk, addr_a => address_a, addr_b => address_b, wr_en => write_regs, a_o => reg_a_out, b_o => reg_b_out);
abacus: alu
port map (reg_a_out, reg_b_out, a_or_l, alu_opcode, alu_out);
program_counter: pc
port map (reset, pc_clock, load_pc, reg_a_out, pc_to_rom);
program_rom: prog_rom
port map (pc_to_rom, rom_out);
reg_mux: mux_2_1
port map (alu_out, immediate, alu_or_imm, reg_val);
brain: control
port map (rom_out, clk, reset, mem_ready, a_or_l, alu_opcode, address_a, address_b, reg_wr_addr, immediate, control_to_pc, load_pc, write_regs, alu_or_imm, pc_clock, curr_state);
end cowgirl_arch;
/tags/start/regsiters.vhdl
0,0 → 1,83
-- 10/24/2005
-- General Purpose Register Bank
 
library ieee;
use ieee.std_logic_1164.all;
 
entity registers is port(
d: in std_logic_vector(15 downto 0);
clk: in std_logic;
addr_a: in std_logic_vector(2 downto 0);
addr_b: in std_logic_vector(2 downto 0);
wr_en: in std_logic;
a_o: out std_logic_vector(15 downto 0);
b_o: out std_logic_vector(15 downto 0)
);
end registers;
 
architecture regs_arch of registers is
 
component reg port(
d: in std_logic_vector(15 downto 0);
clk: in std_logic;
wr_en: in std_logic;
q: out std_logic_vector(15 downto 0)
);
end component;
 
component reg_dec port(
addr: in std_logic_vector(2 downto 0);
en0: out std_logic;
en1: out std_logic;
en2: out std_logic;
en3: out std_logic;
en4: out std_logic;
en5: out std_logic;
en6: out std_logic;
en7: out std_logic
);
end component;
 
component mux_8_1 port(
a: in std_logic_vector(15 downto 0);
b: in std_logic_vector(15 downto 0);
c: in std_logic_vector(15 downto 0);
d: in std_logic_vector(15 downto 0);
e: in std_logic_vector(15 downto 0);
f: in std_logic_vector(15 downto 0);
g: in std_logic_vector(15 downto 0);
h: in std_logic_vector(15 downto 0);
sel: in std_logic_vector(2 downto 0);
o: out std_logic_vector(15 downto 0)
);
end component;
 
signal w0, w1, w2, w3, w4, w5, w6, w7: std_logic;
signal q0, q1, q2, q3, q4, q5, q6, q7: std_logic_vector(15 downto 0);
signal wr_clk: std_logic;
 
begin
wr_clk <= wr_en and clk;
decode: reg_dec
port map(addr_a, w0, w1, w2, w3, w4, w5, w6, w7);
r0: reg
port map(d, wr_clk, w0, q0);
r1: reg
port map(d, wr_clk, w1, q1);
r2: reg
port map(d, wr_clk, w2, q2);
r3: reg
port map(d, wr_clk, w3, q3);
r4: reg
port map(d, wr_clk, w4, q4);
r5: reg
port map(d, wr_clk, w5, q5);
r6: reg
port map(d, wr_clk, w6, q6);
r7: reg
port map(d, wr_clk, w7, q7);
out_mux_a: mux_8_1
port map(q0, q1, q2, q3, q4, q5, q6, q7, addr_a, a_o);
out_mux_b: mux_8_1
port map(q0, q1, q2, q3, q4, q5, q6, q7, addr_b, b_o);
end regs_arch;
/tags/start/arithmetic.vhdl
0,0 → 1,40
-- ALU
-- 10/24/05
-- Everything here works except for division
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
 
entity arithmetic is port(
a: in signed(15 downto 0);
b: in signed(15 downto 0);
fcn: in std_logic_vector(2 downto 0);
o: out signed(15 downto 0);
m_o: out signed(31 downto 0)
);
end arithmetic;
 
architecture arith_arch of arithmetic is
 
signal temp: signed(31 downto 0);
 
begin
arith_logic: process(fcn, a, b)
begin
case fcn is
when "000" => -- add
o <= a + b;
when "001" => -- subtract
o <= a - b;
when "010" => -- multiply
m_o <= a * b;
when "011" => -- divide
--o <= a / b;
when "100" => -- 2's complement inverse
o <= signed((not std_logic_vector(a))) + '1';
when others =>
o <= x"0000";
end case;
end process arith_logic;
end arith_arch;
/tags/start/mux_2_1.vhdl
0,0 → 1,22
library ieee;
use ieee.std_logic_1164.all;
 
entity mux_2_1 is port(
a: in std_logic_vector(15 downto 0);
b: in std_logic_vector(15 downto 0);
sel: in std_logic;
o: out std_logic_vector(15 downto 0)
);
end mux_2_1;
 
architecture mux_arch of mux_2_1 is
begin
process(sel, a, b)
begin
if sel = '0' then
o <= a;
else
o <= b;
end if;
end process;
end mux_arch;
/tags/start/regtest.vhdl
0,0 → 1,53
library ieee;
use ieee.std_logic_1164.all;
 
entity prog_rom is port (
input: in std_logic_vector(15 downto 0);
output: out std_logic_vector(15 downto 0)
);
end;
 
architecture rom_arch of prog_rom is
begin
process(input)
begin
case input is
when "0000000000000000" =>
output <= "0100000000000010";
when "0000000000000001" =>
output <= "0100000000000001";
when "0000000000000010" =>
output <= "0100001000000100";
when "0000000000000011" =>
output <= "0100001000000001";
when "0000000000000100" =>
output <= "0100010000000110";
when "0000000000000101" =>
output <= "0100010000000001";
when "0000000000000110" =>
output <= "0100011000010010";
when "0000000000000111" =>
output <= "0100011000001101";
when "0000000000001000" =>
output <= "0100100000000000";
when "0000000000001001" =>
output <= "0100100000001001";
when "0000000000001010" =>
output <= "0100101000000010";
when "0000000000001011" =>
output <= "0100101000000011";
when "0000000000001100" =>
output <= "0100110000001100";
when "0000000000001101" =>
output <= "0100110000001101";
when "0000000000001110" =>
output <= "0100111000001110";
when "0000000000001111" =>
output <= "0100111000001111";
when "0000000000010000" =>
output <= x"2660";
when others =>
output <= "1111000000000000";
end case;
end process;
end;
/tags/start/logical.vhd
0,0 → 1,36
-- 10/25/2005
-- Logical Unit
 
library ieee;
use ieee.std_logic_1164.all;
 
entity logical is port(
a: in std_logic_vector(15 downto 0);
b: in std_logic_vector(15 downto 0);
fcn: in std_logic_vector(2 downto 0);
o: out std_logic_vector(15 downto 0)
);
end logical;
 
architecture logic_arch of logical is
begin
logical_logic: process(fcn)
begin
case fcn is
when "000" => -- not
o <= not(a);
when "001" => -- and
o <= a and b;
when "010" => -- or
o <= a or b;
when "011" => -- xor
o <= a xor b;
when "100" => -- nand
o <= a nand b;
when "101" => -- nor
o <= a nor b;
when others =>
o <= x"0000";
end case;
end process logical_logic;
end logic_arch;
/tags/start/control.vhdl
0,0 → 1,181
-- 10/24/2005
-- Control Unit
 
 
 
library ieee;
use ieee.std_logic_1164.all;
 
entity control is port(
instr: in std_logic_vector(15 downto 0);
clk: in std_logic;
reset: in std_logic;
mem_ready: in std_logic;
a_or_l: out std_logic;
op: out std_logic_vector(2 downto 0);
addr_a: out std_logic_vector(2 downto 0);
addr_b: out std_logic_vector(2 downto 0);
reg_addr: out std_logic_vector(2 downto 0);
to_regs: out std_logic_vector(15 downto 0);
to_pc: out std_logic_vector(15 downto 0);
load_pc: out std_logic;
reg_wr: out std_logic;
alu_or_imm: out std_logic;
next_instr: out std_logic;
curr_state: out std_logic_vector(15 downto 0)
);
end control;
 
architecture control_arch of control is
type state_type is (idle, alu_arith, alu_logic, load_imm_lo, load_imm_hi, mov_r, mov_w, mem, len, jmp_br, save_addr, wr_pc, halt, ret, compare, set_flags, write_res, alu_wait);
signal state, next_state : state_type;
 
signal return_addr: std_logic_vector(15 downto 0);
signal temp_imm : std_logic_vector(15 downto 0) := x"0000";
 
begin
-- don't forget to put the instruction in the sensitivity list!!!
-- if you don't, nothing will happen, since the code won't run when the
-- instruction changes!!
state_logic:process(state, instr)
begin
case state is
when idle =>
curr_state <= x"0000";
--initialize all signals to zero
next_instr <= '1';
a_or_l <= '0';
op <= "000";
addr_a <= "000";
addr_b <= "000";
--reg_addr <= "000";
to_regs <= x"0000";
to_pc <= x"0000";
load_pc <= '0';
reg_wr <= '0';
--alu_or_imm <= '0'; -- 0 for alu, 1 for immediate
case instr(15 downto 12) is
when "0000" => -- nop
next_state <= idle;
when "0001" => -- return
next_state <= ret;
when "0010" => -- alu arithmetic
next_state <= alu_arith;
when "0011" => -- alu logic
next_state <= alu_logic;
when "0100" => -- load immediate
if instr(0) = '0' then
next_state <= load_imm_lo;
else
next_state <= load_imm_hi;
end if;
when "0101" => -- jump or branch
next_state <= jmp_br;
--when "0110" => -- shift
--next_state <= shift;
when "0111" => -- compare
next_state <= compare;
when "1000" => -- move
next_state <= mov_r;
when "1001" => -- memory access
next_state <= mem;
when "1110" => -- len
next_state <= len;
when "1111" => -- halt
next_state <= halt;
when others =>
next_state <= idle;
end case;
when alu_arith =>
curr_state <= x"0001";
next_instr <= '0';
alu_or_imm <= '0';
a_or_l <= '0';
op <= instr(2 downto 0);
--op <= "001";
addr_a <= instr(8 downto 6);
addr_b <= instr(5 downto 3);
--next_state <= write_res;
next_state <= alu_wait;
when alu_wait =>
curr_state <= x"001A";
next_instr <= '0';
next_state <= write_res;
when alu_logic =>
curr_state <= x"0002";
next_instr <= '0';
a_or_l <= '1';
op <= instr(2 downto 0);
addr_a <= instr(8 downto 6);
addr_b <= instr(5 downto 3);
next_state <= write_res;
when load_imm_lo =>
next_instr <= '0';
alu_or_imm <= '1';
--reg_addr <= instr(11 downto 9);
addr_a <= instr(11 downto 9);
curr_state <= x"003A";
temp_imm(7 downto 0) <= instr(8 downto 1);
next_state <= idle;
when load_imm_hi =>
curr_state <= x"003B";
next_instr <= '0';
alu_or_imm <= '1';
--reg_addr <= instr(11 downto 9);
addr_a <= instr(11 downto 9);
temp_imm(15 downto 8) <= instr(8 downto 1);
to_regs <= temp_imm;
reg_wr <= '1';
next_state <= idle;
--next_state <= write_res;
when mov_r =>
curr_state <= x"0004";
next_instr <= '0';
addr_a <= instr(8 downto 6);
next_state <= mov_w;
when mov_w =>
curr_state <= x"0005";
next_instr <= '0';
reg_wr <= '1';
reg_addr <= instr(11 downto 9);
next_state <= idle;
when wr_pc =>
curr_state <= x"0006";
next_instr <= '0';
load_pc <= '1';
to_pc <= return_addr;
when write_res =>
curr_state <= x"0007";
next_instr <= '0';
reg_addr <= instr(11 downto 9);
reg_wr <= '1';
next_state <= idle;
when halt =>
curr_state <= x"0008";
next_instr <= '0';
next_state <= halt;
when others =>
curr_state <= x"0009";
next_instr <= '0';
next_state <= idle;
end case;
end process state_logic;
 
state_reg:process(clk, reset)
begin
if reset = '1' then
state <= idle;
-- i set clk='0' here because it was transitioning states after 1 full
-- clock cycle, which made things not work, since i'm looking at the
-- instruction for how to process things. and the instruction has
-- changed by the time the state changes
-- that doesn't seem to be working though, and it confuses me
elsif (clk'EVENT and clk='1') then
state <= next_state;
end if;
end process state_reg;
end control_arch;
/tags/start/mux_8_1.vhdl
0,0 → 1,40
library ieee;
use ieee.std_logic_1164.all;
 
entity mux_8_1 is port(
a: in std_logic_vector(15 downto 0);
b: in std_logic_vector(15 downto 0);
c: in std_logic_vector(15 downto 0);
d: in std_logic_vector(15 downto 0);
e: in std_logic_vector(15 downto 0);
f: in std_logic_vector(15 downto 0);
g: in std_logic_vector(15 downto 0);
h: in std_logic_vector(15 downto 0);
sel: in std_logic_vector(2 downto 0);
o: out std_logic_vector(15 downto 0)
);
end mux_8_1;
 
architecture mux8_arch of mux_8_1 is
begin
process(sel, a, b)
begin
if sel = "000" then
o <= a;
elsif sel = "001" then
o <= b;
elsif sel = "010" then
o <= c;
elsif sel = "011" then
o <= d;
elsif sel = "100" then
o <= e;
elsif sel = "101" then
o <= f;
elsif sel = "110" then
o <= g;
elsif sel = "111" then
o <= h;
end if;
end process;
end mux8_arch;
/tags/start/reg_decode.vhdl
0,0 → 1,33
-- 10/24/2005
-- Register Address Decoding
 
library ieee;
use ieee.std_logic_1164.all;
 
entity reg_dec is port(
addr: in std_logic_vector(2 downto 0);
en0: out std_logic;
en1: out std_logic;
en2: out std_logic;
en3: out std_logic;
en4: out std_logic;
en5: out std_logic;
en6: out std_logic;
en7: out std_logic
);
end reg_dec;
 
architecture rd_arch of reg_dec is
begin
process(addr)
begin
en0 <= (not addr(2)) and (not addr(1)) and (not addr(0));
en1 <= (not addr(2)) and (not addr(1)) and addr(0);
en2 <= (not addr(2)) and addr(1) and (not addr(0));
en3 <= (not addr(2)) and addr(1) and addr(0);
en4 <= addr(2) and (not addr(1)) and (not addr(0));
en5 <= addr(2) and (not addr(1)) and addr(0);
en6 <= addr(2) and addr(1) and (not addr(0));
en7 <= addr(2) and addr(1) and addr(0);
end process;
end rd_arch;
/tags/start/alu.vhdl
0,0 → 1,57
-- 10/24/2005
-- alu
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
 
entity alu is port(
a: in std_logic_vector(15 downto 0);
b: in std_logic_vector(15 downto 0);
a_or_l: in std_logic;
op: in std_logic_vector(2 downto 0);
o: out std_logic_vector(15 downto 0)
);
end alu;
 
architecture alu_arch of alu is
 
component arithmetic port(
a: in signed(15 downto 0);
b: in signed(15 downto 0);
fcn: in std_logic_vector(2 downto 0);
o: out signed(15 downto 0);
m_o: out signed(31 downto 0)
);
end component;
 
component logical port(
a: in std_logic_vector(15 downto 0);
b: in std_logic_vector(15 downto 0);
fcn: in std_logic_vector(2 downto 0);
o: out std_logic_vector(15 downto 0)
);
end component;
 
component mux_2_1 port(
a: in std_logic_vector(15 downto 0);
b: in std_logic_vector(15 downto 0);
sel: in std_logic;
o: out std_logic_vector(15 downto 0)
);
end component;
 
signal s_a, s_b, s_o: signed(15 downto 0);
signal l_o: std_logic_vector(15 downto 0);
 
begin
s_a <= signed(a);
s_b <= signed(b);
arith: arithmetic
port map(s_a, s_b, op, s_o);
logic: logical
port map(a, b, op, l_o);
mux: mux_2_1
port map(std_logic_vector(s_o), l_o, a_or_l, o);
end alu_arch;
/tags/start/pc.vhdl
0,0 → 1,38
-- 10/24/2005
-- Program Counter
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
 
entity pc is port(
reset: in std_logic;
clk: in std_logic;
load: in std_logic;
d: in std_logic_vector(15 downto 0);
c: out std_logic_vector(15 downto 0)
);
end pc;
 
architecture pc_arch of pc is
 
signal count: unsigned(15 downto 0);
--signal count : std_logic_vector(15 downto 0);
 
begin
count_logic:process(clk, reset, load)
begin
if reset = '1' then
count <= x"0000";
elsif (clk'EVENT and clk='1') then
count <= count + '1';
elsif load = '1' then
count <= unsigned(d);
end if;
-- don't assign the output here!
-- if you do, the count will change on the falling
-- edge of the clock! and that's lame!
--c <= count;
end process count_logic;
c <= std_logic_vector(count);
end pc_arch;

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.