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

Subversion Repositories mlite

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 127 to Rev 128
    Reverse comparison

Rev 127 → Rev 128

/trunk/vhdl/pc_next.vhd
26,9 → 26,7
end; --pc_next
 
architecture logic of pc_next is
-- type pc_source_type is (from_inc4, from_opcode25_0, from_branch,
-- from_lbranch);
signal pc_reg : std_logic_vector(31 downto 2); --:= ZERO(31 downto 2);
signal pc_reg : std_logic_vector(31 downto 2);
begin
 
pc_next: process(clk, reset_in, pc_new, take_branch, pause_in,
38,16 → 36,18
pc_inc := bv_increment(pc_reg); --pc_reg+1
 
case pc_source is
when from_inc4 =>
when FROM_INC4 =>
pc_next := pc_inc;
when from_opcode25_0 =>
when FROM_OPCODE25_0 =>
pc_next := pc_reg(31 downto 28) & opcode25_0;
when others => --from_branch | from_lbranch =>
when FROM_BRANCH | FROM_LBRANCH =>
if take_branch = '1' then
pc_next := pc_new;
else
pc_next := pc_inc;
end if;
when others =>
pc_next := pc_inc;
end case;
 
if pause_in = '1' then
/trunk/vhdl/mem_ctrl.vhd
44,7 → 44,7
 
architecture logic of mem_ctrl is
--"00" = big_endian; "11" = little_endian
constant little_endian : std_logic_vector(1 downto 0) := "00";
constant ENDIAN_MODE : std_logic_vector(1 downto 0) := "00";
signal opcode_reg : std_logic_vector(31 downto 0);
signal next_opcode_reg : std_logic_vector(31 downto 0);
 
92,8 → 92,14
 
GEN_REGS2: process(clk, address_data, write_next_sig, byte_sel_next_sig)
begin
if rising_edge(clk) then
if reset_in = '1' then
if ACCURATE_TIMING then
address_reg <= ZERO;
write_reg <= '0';
byte_sel_reg <= "0000";
end if;
elsif rising_edge(clk) then
if ACCURATE_TIMING then
address_reg <= address_data;
write_reg <= write_next_sig;
byte_sel_reg <= byte_sel_next_sig;
132,10 → 138,11
mem_data_w_v := ZERO;
 
case mem_source is
when mem_read32 =>
when MEM_READ32 =>
data := mem_data_r;
when mem_read16 | mem_read16s =>
if address_reg(1) = little_endian(1) then
 
when MEM_READ16 | MEM_READ16S =>
if address_reg(1) = ENDIAN_MODE(1) then
data(15 downto 0) := mem_data_r(31 downto 16);
else
data(15 downto 0) := mem_data_r(15 downto 0);
145,8 → 152,9
else
data(31 downto 16) := ONES(31 downto 16);
end if;
when mem_read8 | mem_read8s =>
bits := address_reg(1 downto 0) xor little_endian;
 
when MEM_READ8 | MEM_READ8s =>
bits := address_reg(1 downto 0) xor ENDIAN_MODE;
case bits is
when "00" => data(7 downto 0) := mem_data_r(31 downto 24);
when "01" => data(7 downto 0) := mem_data_r(23 downto 16);
153,28 → 161,31
when "10" => data(7 downto 0) := mem_data_r(15 downto 8);
when others => data(7 downto 0) := mem_data_r(7 downto 0);
end case;
if mem_source = mem_read8 or data(7) = '0' then
if mem_source = MEM_READ8 or data(7) = '0' then
data(31 downto 8) := ZERO(31 downto 8);
else
data(31 downto 8) := ONES(31 downto 8);
end if;
when mem_write32 =>
 
when MEM_WRITE32 =>
write_next := '1';
mem_data_w_v := data_write;
byte_sel_next := "1111";
when mem_write16 =>
 
when MEM_WRITE16 =>
write_next := '1';
mem_data_w_v := data_write(15 downto 0) & data_write(15 downto 0);
if address_data(1) = little_endian(1) then
if address_data(1) = ENDIAN_MODE(1) then
byte_sel_next := "1100";
else
byte_sel_next := "0011";
end if;
when mem_write8 =>
 
when MEM_WRITE8 =>
write_next := '1';
mem_data_w_v := data_write(7 downto 0) & data_write(7 downto 0) &
data_write(7 downto 0) & data_write(7 downto 0);
bits := address_data(1 downto 0) xor little_endian;
bits := address_data(1 downto 0) xor ENDIAN_MODE;
case bits is
when "00" =>
byte_sel_next := "1000";
185,8 → 196,10
when others =>
byte_sel_next := "0001";
end case;
 
when others =>
end case;
 
byte_sel_next_sig <= byte_sel_next;
write_next_sig <= write_next;
207,6 → 220,7
mem_state_next := STATE_ADDR;
end if;
end if;
 
when STATE_ADDR => --address lines pre-hold
address := address_reg;
write_line := write_reg;
223,6 → 237,7
mem_state_next := STATE_FETCH; --2 cycle access
end if;
end if;
 
when STATE_WRITE =>
pause := '1';
address := address_reg;
231,6 → 246,7
if pause_in = '0' then
mem_state_next := STATE_PAUSE;
end if;
 
when OTHERS => --STATE_PAUSE address lines post-hold
address := address_reg;
write_line := write_reg;
/trunk/vhdl/tbench.vhd
39,6 → 39,7
begin --architecture
clk <= not clk after 50 ns;
reset <= '0' after 500 ns;
uart_read <= '0';
 
--Uncomment the line below to test interrupts
-- interrupt <= '1' after 20 us when interrupt = '0' else '0' after 400 ns;
/trunk/vhdl/shifter.vhd
32,7 → 32,7
signal fills : std_logic_vector(31 downto 16);
 
begin
fills <= "1111111111111111" when shift_func = shift_right_signed and value(31) = '1' else
fills <= "1111111111111111" when shift_func = SHIFT_RIGHT_SIGNED and value(31) = '1' else
"0000000000000000";
shift1L <= value(30 downto 0) & '0' when shift_amount(0) = '1' else value;
shift2L <= shift1L(29 downto 0) & "00" when shift_amount(1) = '1' else shift1L;
50,8 → 50,8
GENERIC_SHIFTER: if shifter_type = "GENERIC" generate
-- synthesis translate_on
 
c_shift <= shift16L when shift_func = shift_left_unsigned else
shift16R when shift_func = shift_right_unsigned or shift_func = shift_right_signed else
c_shift <= shift16L when shift_func = SHIFT_LEFT_UNSIGNED else
shift16R when shift_func = SHIFT_RIGHT_UNSIGNED or shift_func = SHIFT_RIGHT_SIGNED else
ZERO;
 
-- synthesis translate_off
62,10 → 62,10
AREA_OPTIMIZED_SHIFTER: if shifter_type = "AREA_OPTIMIZED" generate
 
c_shift <= shift16L when shift_func = shift_left_unsigned else (others => 'Z');
c_shift <= shift16R when shift_func = shift_right_unsigned or
shift_func = shift_right_signed else (others => 'Z');
c_shift <= ZERO when shift_func = shift_nothing else (others => 'Z');
c_shift <= shift16L when shift_func = SHIFT_LEFT_UNSIGNED else (others => 'Z');
c_shift <= shift16R when shift_func = SHIFT_RIGHT_UNSIGNED or
shift_func = SHIFT_RIGHT_SIGNED else (others => 'Z');
c_shift <= ZERO when shift_func = SHIFT_NOTHING else (others => 'Z');
 
end generate;
 
/trunk/vhdl/pipeline.vhd
64,9 → 64,9
variable pause_mult_clock : std_logic;
variable freeze_pipeline : std_logic;
begin
if (pc_source /= from_inc4 and pc_source /= from_opcode25_0) or
mem_source /= mem_fetch or
(mult_func = mult_read_lo or mult_func = mult_read_hi) then
if (pc_source /= FROM_INC4 and pc_source /= FROM_OPCODE25_0) or
mem_source /= MEM_FETCH or
(mult_func = MULT_READ_LO or mult_func = MULT_READ_HI) then
pause_mult_clock := '1';
else
pause_mult_clock := '0';
76,7 → 76,7
pause_pipeline <= pause_mult_clock and pause_enable_reg;
rd_indexD <= rd_index_reg;
 
if c_source_reg = c_from_alu then
if c_source_reg = C_FROM_ALU then
reg_dest_delay <= c_bus; --delayed by 1 clock cycle via a_busD & b_busD
else
reg_dest_delay <= reg_dest_reg; --need to delay 1 clock cycle from reg_dest
84,12 → 84,19
reg_destD <= reg_dest_delay;
 
if reset = '1' then
pause_enable_reg <= '1';
a_busD <= ZERO;
b_busD <= ZERO;
alu_funcD <= ALU_NOTHING;
shift_funcD <= SHIFT_NOTHING;
mult_funcD <= MULT_NOTHING;
reg_dest_reg <= ZERO;
c_source_reg <= "000";
rd_index_reg <= "000000";
pause_enable_reg <= '0';
elsif rising_edge(clk) then
if freeze_pipeline = '0' then
if (rs_index = "000000" or rs_index /= rd_index_reg) or
(a_source /= a_from_reg_source or pause_enable_reg = '0') then
(a_source /= A_FROM_REG_SOURCE or pause_enable_reg = '0') then
a_busD <= a_bus;
else
a_busD <= reg_dest_delay; --rs from previous operation (bypass stage)
96,7 → 103,7
end if;
 
if (rt_index = "000000" or rt_index /= rd_index_reg) or
(b_source /= b_from_reg_target or pause_enable_reg = '0') then
(b_source /= B_FROM_REG_TARGET or pause_enable_reg = '0') then
b_busD <= b_bus;
else
b_busD <= reg_dest_delay; --rt from previous operation
/trunk/vhdl/reg_bank.vhd
44,9 → 44,6
signal addr_a1, addr_a2, addr_b : std_logic_vector(4 downto 0);
signal data_out1, data_out2 : std_logic_vector(31 downto 0);
signal write_enable : std_logic;
-- signal sig_false : std_logic := '0';
-- signal sig_true : std_logic := '1';
-- signal zero_sig : std_logic_vector(15 downto 0) := ZERO(15 downto 0);
 
begin
/trunk/vhdl/mlite_pack.vhd
21,97 → 21,82
constant HIGH_Z : std_logic_vector(31 downto 0) :=
"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
-- type alu_function_type is (alu_nothing, alu_add, alu_subtract,
-- alu_less_than, alu_less_than_signed,
-- alu_or, alu_and, alu_xor, alu_nor);
subtype alu_function_type is std_logic_vector(3 downto 0);
constant alu_nothing : alu_function_type := "0000";
constant alu_add : alu_function_type := "0001";
constant alu_subtract : alu_function_type := "0010";
constant alu_less_than : alu_function_type := "0011";
constant alu_less_than_signed : alu_function_type := "0100";
constant alu_or : alu_function_type := "0101";
constant alu_and : alu_function_type := "0110";
constant alu_xor : alu_function_type := "0111";
constant alu_nor : alu_function_type := "1000";
constant ALU_NOTHING : alu_function_type := "0000";
constant ALU_ADD : alu_function_type := "0001";
constant ALU_SUBTRACT : alu_function_type := "0010";
constant ALU_LESS_THAN : alu_function_type := "0011";
constant ALU_LESS_THAN_SIGNED : alu_function_type := "0100";
constant ALU_OR : alu_function_type := "0101";
constant ALU_AND : alu_function_type := "0110";
constant ALU_XOR : alu_function_type := "0111";
constant ALU_NOR : alu_function_type := "1000";
 
-- type shift_function_type is (
-- shift_nothing, shift_left_unsigned,
-- shift_right_signed, do_right_unsigned);
subtype shift_function_type is std_logic_vector(1 downto 0);
constant shift_nothing : shift_function_type := "00";
constant shift_left_unsigned : shift_function_type := "01";
constant shift_right_signed : shift_function_type := "11";
constant shift_right_unsigned : shift_function_type := "10";
constant SHIFT_NOTHING : shift_function_type := "00";
constant SHIFT_LEFT_UNSIGNED : shift_function_type := "01";
constant SHIFT_RIGHT_SIGNED : shift_function_type := "11";
constant SHIFT_RIGHT_UNSIGNED : shift_function_type := "10";
 
-- type mult_function_type is (
-- mult_nothing, mult_read_lo, mult_read_hi, mult_write_lo,
-- mult_write_hi, mult_mult, mult_divide, mult_signed_divide);
subtype mult_function_type is std_logic_vector(3 downto 0);
constant mult_nothing : mult_function_type := "0000";
constant mult_read_lo : mult_function_type := "0001";
constant mult_read_hi : mult_function_type := "0010";
constant mult_write_lo : mult_function_type := "0011";
constant mult_write_hi : mult_function_type := "0100";
constant mult_mult : mult_function_type := "0101";
constant mult_signed_mult : mult_function_type := "0110";
constant mult_divide : mult_function_type := "0111";
constant mult_signed_divide : mult_function_type := "1000";
constant MULT_NOTHING : mult_function_type := "0000";
constant MULT_READ_LO : mult_function_type := "0001";
constant MULT_READ_HI : mult_function_type := "0010";
constant MULT_WRITE_LO : mult_function_type := "0011";
constant MULT_WRITE_HI : mult_function_type := "0100";
constant MULT_MULT : mult_function_type := "0101";
constant MULT_SIGNED_MULT : mult_function_type := "0110";
constant MULT_DIVIDE : mult_function_type := "0111";
constant MULT_SIGNED_DIVIDE : mult_function_type := "1000";
 
-- type a_source_type is (from_reg_source, from_imm10_6);
subtype a_source_type is std_logic_vector(1 downto 0);
constant a_from_reg_source : a_source_type := "00";
constant a_from_imm10_6 : a_source_type := "01";
constant a_from_pc : a_source_type := "10";
constant A_FROM_REG_SOURCE : a_source_type := "00";
constant A_FROM_IMM10_6 : a_source_type := "01";
constant A_FROM_PC : a_source_type := "10";
 
-- type b_source_type is (from_reg_target, from_imm, from_signed_imm);
subtype b_source_type is std_logic_vector(1 downto 0);
constant b_from_reg_target : b_source_type := "00";
constant b_from_imm : b_source_type := "01";
constant b_from_signed_imm : b_source_type := "10";
constant b_from_immX4 : b_source_type := "11";
constant B_FROM_REG_TARGET : b_source_type := "00";
constant B_FROM_IMM : b_source_type := "01";
constant B_FROM_SIGNED_IMM : b_source_type := "10";
constant B_FROM_IMMX4 : b_source_type := "11";
 
-- type c_source_type is (from_null, from_alu, from_shift,
-- from_mult, from_memory, from_pc, from_imm_shift16,
-- from_reg_source_nez, from_reg_source_eqz);
subtype c_source_type is std_logic_vector(2 downto 0);
constant c_from_null : c_source_type := "000";
constant c_from_alu : c_source_type := "001";
constant c_from_shift : c_source_type := "001"; --same as alu
constant c_from_mult : c_source_type := "001"; --same as alu
constant c_from_memory : c_source_type := "010";
constant c_from_pc : c_source_type := "011";
constant c_from_pc_plus4 : c_source_type := "100";
constant c_from_imm_shift16: c_source_type := "101";
constant c_from_reg_sourcen: c_source_type := "110";
constant C_FROM_NULL : c_source_type := "000";
constant C_FROM_ALU : c_source_type := "001";
constant C_FROM_SHIFT : c_source_type := "001"; --same as alu
constant C_FROM_MULT : c_source_type := "001"; --same as alu
constant C_FROM_MEMORY : c_source_type := "010";
constant C_FROM_PC : c_source_type := "011";
constant C_FROM_PC_PLUS4 : c_source_type := "100";
constant C_FROM_IMM_SHIFT16: c_source_type := "101";
constant C_FROM_REG_SOURCEN: c_source_type := "110";
 
-- type pc_source_type is (from_inc4, from_opcode25_0, from_branch, from_lbranch);
subtype pc_source_type is std_logic_vector(1 downto 0);
constant from_inc4 : pc_source_type := "00";
constant from_opcode25_0 : pc_source_type := "01";
constant from_branch : pc_source_type := "10";
constant from_lbranch : pc_source_type := "11";
constant FROM_INC4 : pc_source_type := "00";
constant FROM_OPCODE25_0 : pc_source_type := "01";
constant FROM_BRANCH : pc_source_type := "10";
constant FROM_LBRANCH : pc_source_type := "11";
 
subtype branch_function_type is std_logic_vector(2 downto 0);
constant branch_ltz : branch_function_type := "000";
constant branch_lez : branch_function_type := "001";
constant branch_eq : branch_function_type := "010";
constant branch_ne : branch_function_type := "011";
constant branch_gez : branch_function_type := "100";
constant branch_gtz : branch_function_type := "101";
constant branch_yes : branch_function_type := "110";
constant BRANCH_LTZ : branch_function_type := "000";
constant BRANCH_LEZ : branch_function_type := "001";
constant BRANCH_EQ : branch_function_type := "010";
constant BRANCH_NE : branch_function_type := "011";
constant BRANCH_GEZ : branch_function_type := "100";
constant BRANCH_GTZ : branch_function_type := "101";
constant BRANCH_YES : branch_function_type := "110";
 
-- mode(32=1,16=2,8=3), signed, write
subtype mem_source_type is std_logic_vector(3 downto 0);
constant mem_fetch : mem_source_type := "0000";
constant mem_read32 : mem_source_type := "0100";
constant mem_write32 : mem_source_type := "0101";
constant mem_read16 : mem_source_type := "1000";
constant mem_read16s : mem_source_type := "1010";
constant mem_write16 : mem_source_type := "1001";
constant mem_read8 : mem_source_type := "1100";
constant mem_read8s : mem_source_type := "1110";
constant mem_write8 : mem_source_type := "1101";
constant MEM_FETCH : mem_source_type := "0000";
constant MEM_READ32 : mem_source_type := "0100";
constant MEM_WRITE32 : mem_source_type := "0101";
constant MEM_READ16 : mem_source_type := "1000";
constant MEM_READ16s : mem_source_type := "1010";
constant MEM_WRITE16 : mem_source_type := "1001";
constant MEM_READ8 : mem_source_type := "1100";
constant MEM_READ8s : mem_source_type := "1110";
constant MEM_WRITE8 : mem_source_type := "1101";
 
function bv_to_integer(bv: in std_logic_vector) return integer;
function bv_adder(a : in std_logic_vector(32 downto 0);
339,6 → 324,7
mult_type : string := "GENERIC");
port (
clk : in std_logic;
reset_in : in std_logic;
a, b : in std_logic_vector(31 downto 0);
mult_func : in mult_function_type;
c_mult : out std_logic_vector(31 downto 0);
/trunk/vhdl/ram.vhd
58,6 → 58,7
file load_file : text is in "code.txt";
variable hex_file_line : line;
begin
 
--load in the ram executable image
if index = 0 then
while not endfile(load_file) loop
/trunk/vhdl/control.vhd
43,22 → 43,6
end; --entity control
 
architecture logic of control is
-- type alu_function_type is (alu_nothing, alu_add, alu_subtract,
-- alu_less_than, alu_less_than_signed,
-- alu_or, alu_and, alu_xor, alu_nor);
-- type shift_function_type is (
-- shift_nothing, shift_left_unsigned,
-- shift_right_signed, shift_right_unsigned);
-- type mult_function_type is (
-- mult_nothing, mult_read_lo, mult_read_hi, mult_write_lo,
-- mult_write_hi, mult_mult, mult_divide, mult_signed_divide);
-- type a_source_type is (from_reg_source, from_imm10_6);
-- type b_source_type is (from_reg_target, from_imm, from_signed_imm);
-- type c_source_type is (from_null, from_alu, from_shift,
-- from_mult, from_memory, from_pc, from_imm_shift16,
-- from_reg_source_nez, from_reg_source_eqz);
-- type pc_source_type is (from_inc4, from_inc8, from_reg_source,
-- from_opcode25_0, from_branch, from_lbranch);
begin
 
control_proc: process(opcode, intr_signal)
76,15 → 60,15
variable branch_function: branch_function_type;
variable mem_source : mem_source_type;
begin
alu_function := alu_nothing;
shift_function := shift_nothing;
mult_function := mult_nothing;
a_source := a_from_reg_source;
b_source := b_from_reg_target;
c_source := c_from_null;
pc_source := from_inc4;
branch_function := branch_eq;
mem_source := mem_fetch;
alu_function := ALU_NOTHING;
shift_function := SHIFT_NOTHING;
mult_function := MULT_NOTHING;
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_REG_TARGET;
c_source := C_FROM_NULL;
pc_source := FROM_INC4;
branch_function := BRANCH_EQ;
mem_source := MEM_FETCH;
op := opcode(31 downto 26);
rs := '0' & opcode(25 downto 21);
rt := '0' & opcode(20 downto 16);
97,94 → 81,124
when "000000" => --SPECIAL
case func is
when "000000" => --SLL r[rd]=r[rt]<<re;
a_source := a_from_imm10_6;
c_source := c_from_shift;
shift_function := shift_left_unsigned;
a_source := A_FROM_IMM10_6;
c_source := C_FROM_SHIFT;
shift_function := SHIFT_LEFT_UNSIGNED;
 
when "000010" => --SRL r[rd]=u[rt]>>re;
a_source := a_from_imm10_6;
c_source := c_from_shift;
shift_function := shift_right_unsigned;
a_source := A_FROM_IMM10_6;
c_source := C_FROM_shift;
shift_function := SHIFT_RIGHT_UNSIGNED;
 
when "000011" => --SRA r[rd]=r[rt]>>re;
a_source := a_from_imm10_6;
c_source := c_from_shift;
shift_function := shift_right_signed;
a_source := A_FROM_IMM10_6;
c_source := C_FROM_SHIFT;
shift_function := SHIFT_RIGHT_SIGNED;
 
when "000100" => --SLLV r[rd]=r[rt]<<r[rs];
c_source := c_from_shift;
shift_function := shift_left_unsigned;
c_source := C_FROM_SHIFT;
shift_function := SHIFT_LEFT_UNSIGNED;
 
when "000110" => --SRLV r[rd]=u[rt]>>r[rs];
c_source := c_from_shift;
shift_function := shift_right_unsigned;
c_source := C_FROM_SHIFT;
shift_function := SHIFT_RIGHT_UNSIGNED;
 
when "000111" => --SRAV r[rd]=r[rt]>>r[rs];
c_source := c_from_shift;
shift_function := shift_right_signed;
c_source := C_FROM_SHIFT;
shift_function := SHIFT_RIGHT_SIGNED;
 
when "001000" => --JR s->pc_next=r[rs];
pc_source := from_branch;
alu_function := alu_add;
branch_function := branch_yes;
pc_source := FROM_BRANCH;
alu_function := ALU_ADD;
branch_function := BRANCH_YES;
 
when "001001" => --JALR r[rd]=s->pc_next; s->pc_next=r[rs];
c_source := c_from_pc_plus4;
pc_source := from_branch;
alu_function := alu_add;
branch_function := branch_yes;
c_source := C_FROM_PC_PLUS4;
pc_source := FROM_BRANCH;
alu_function := ALU_ADD;
branch_function := BRANCH_YES;
 
when "001010" => --MOVZ if(!r[rt]) r[rd]=r[rs]; /*IV*/
-- c_source := c_from_reg_source_eqz;
-- c_source := C_FROM_REG_SOURCE_EQZ;
 
when "001011" => --MOVN if(r[rt]) r[rd]=r[rs]; /*IV*/
-- c_source := from_reg_source_nez;
-- c_source := FROM_REG_SOURCE_NEZ;
 
when "001100" => --SYSCALL
-- if(r[4]==0) printf("0x%8.8lx ",r[5]);
 
when "001101" => --BREAK s->wakeup=1;
when "001111" => --SYNC s->wakeup=1;
when "010000" => --MFHI r[rd]=s->hi;
c_source := c_from_mult;
mult_function := mult_read_hi;
c_source := C_FROM_MULT;
mult_function := MULT_READ_HI;
 
when "010001" => --FTHI s->hi=r[rs];
mult_function := mult_write_hi;
mult_function := MULT_WRITE_HI;
 
when "010010" => --MFLO r[rd]=s->lo;
c_source := c_from_mult;
mult_function := mult_read_lo;
c_source := C_FROM_MULT;
mult_function := MULT_READ_LO;
 
when "010011" => --MTLO s->lo=r[rs];
mult_function := mult_write_lo;
mult_function := MULT_WRITE_LO;
 
when "011000" => --MULT s->lo=r[rs]*r[rt]; s->hi=0;
mult_function := mult_signed_mult;
mult_function := MULT_SIGNED_MULT;
 
when "011001" => --MULTU s->lo=r[rs]*r[rt]; s->hi=0;
mult_function := mult_mult;
mult_function := MULT_MULT;
 
when "011010" => --DIV s->lo=r[rs]/r[rt]; s->hi=r[rs]%r[rt];
mult_function := mult_signed_divide;
mult_function := MULT_SIGNED_DIVIDE;
 
when "011011" => --DIVU s->lo=r[rs]/r[rt]; s->hi=r[rs]%r[rt];
mult_function := mult_divide;
mult_function := MULT_DIVIDE;
 
when "100000" => --ADD r[rd]=r[rs]+r[rt];
c_source := c_from_alu;
alu_function := alu_add;
c_source := C_FROM_ALU;
alu_function := ALU_ADD;
 
when "100001" => --ADDU r[rd]=r[rs]+r[rt];
c_source := c_from_alu;
alu_function := alu_add;
c_source := C_FROM_ALU;
alu_function := ALU_ADD;
 
when "100010" => --SUB r[rd]=r[rs]-r[rt];
c_source := c_from_alu;
alu_function := alu_subtract;
c_source := C_FROM_ALU;
alu_function := ALU_SUBTRACT;
 
when "100011" => --SUBU r[rd]=r[rs]-r[rt];
c_source := c_from_alu;
alu_function := alu_subtract;
c_source := C_FROM_ALU;
alu_function := ALU_SUBTRACT;
 
when "100100" => --AND r[rd]=r[rs]&r[rt];
c_source := c_from_alu;
alu_function := alu_and;
c_source := C_FROM_ALU;
alu_function := ALU_AND;
 
when "100101" => --OR r[rd]=r[rs]|r[rt];
c_source := c_from_alu;
alu_function := alu_or;
c_source := C_FROM_ALU;
alu_function := ALU_OR;
 
when "100110" => --XOR r[rd]=r[rs]^r[rt];
c_source := c_from_alu;
alu_function := alu_xor;
c_source := C_FROM_ALU;
alu_function := ALU_XOR;
 
when "100111" => --NOR r[rd]=~(r[rs]|r[rt]);
c_source := c_from_alu;
alu_function := alu_nor;
c_source := C_FROM_ALU;
alu_function := ALU_NOR;
 
when "101010" => --SLT r[rd]=r[rs]<r[rt];
c_source := c_from_alu;
alu_function := alu_less_than_signed;
c_source := C_FROM_ALU;
alu_function := ALU_LESS_THAN_SIGNED;
 
when "101011" => --SLTU r[rd]=u[rs]<u[rt];
c_source := c_from_alu;
alu_function := alu_less_than;
c_source := C_FROM_ALU;
alu_function := ALU_LESS_THAN;
 
when "101101" => --DADDU r[rd]=r[rs]+u[rt];
c_source := c_from_alu;
alu_function := alu_add;
c_source := C_FROM_ALU;
alu_function := ALU_ADD;
 
when "110001" => --TGEU
when "110010" => --TLT
when "110011" => --TLTU
192,113 → 206,138
when "110110" => --TNE
when others =>
end case;
 
when "000001" => --REGIMM
rt := "000000";
rd := "011111";
a_source := a_from_pc;
b_source := b_from_immX4;
alu_function := alu_add;
pc_source := from_branch;
branch_function := branch_gtz;
a_source := A_FROM_PC;
b_source := B_FROM_IMMX4;
alu_function := ALU_ADD;
pc_source := FROM_BRANCH;
branch_function := BRANCH_GTZ;
--if(test) pc=pc+imm*4
 
case rtx is
when "10000" => --BLTZAL r[31]=s->pc_next; branch=r[rs]<0;
c_source := c_from_pc_plus4;
branch_function := branch_ltz;
c_source := C_FROM_PC_PLUS4;
branch_function := BRANCH_LTZ;
 
when "00000" => --BLTZ branch=r[rs]<0;
branch_function := branch_ltz;
branch_function := BRANCH_LTZ;
 
when "10001" => --BGEZAL r[31]=s->pc_next; branch=r[rs]>=0;
c_source := c_from_pc_plus4;
branch_function := branch_gez;
c_source := C_FROM_PC_PLUS4;
branch_function := BRANCH_GEZ;
 
when "00001" => --BGEZ branch=r[rs]>=0;
branch_function := branch_gez;
branch_function := BRANCH_GEZ;
 
when "10010" => --BLTZALL r[31]=s->pc_next; lbranch=r[rs]<0;
c_source := c_from_pc_plus4;
pc_source := from_lbranch;
branch_function := branch_ltz;
c_source := C_FROM_PC_PLUS4;
pc_source := FROM_LBRANCH;
branch_function := BRANCH_LTZ;
 
when "00010" => --BLTZL lbranch=r[rs]<0;
pc_source := from_lbranch;
branch_function := branch_ltz;
pc_source := FROM_LBRANCH;
branch_function := BRANCH_LTZ;
 
when "10011" => --BGEZALL r[31]=s->pc_next; lbranch=r[rs]>=0;
c_source := c_from_pc_plus4;
pc_source := from_lbranch;
branch_function := branch_gez;
c_source := C_FROM_PC_PLUS4;
pc_source := FROM_LBRANCH;
branch_function := BRANCH_GEZ;
 
when "00011" => --BGEZL lbranch=r[rs]>=0;
pc_source := from_lbranch;
branch_function := branch_gez;
pc_source := FROM_LBRANCH;
branch_function := BRANCH_GEZ;
 
when others =>
end case;
 
when "000011" => --JAL r[31]=s->pc_next; s->pc_next=(s->pc&0xf0000000)|target;
c_source := c_from_pc_plus4;
c_source := C_FROM_PC_PLUS4;
rd := "011111";
pc_source := from_opcode25_0;
pc_source := FROM_OPCODE25_0;
 
when "000010" => --J s->pc_next=(s->pc&0xf0000000)|target;
pc_source := from_opcode25_0;
pc_source := FROM_OPCODE25_0;
 
when "000100" => --BEQ branch=r[rs]==r[rt];
a_source := a_from_pc;
b_source := b_from_immX4;
alu_function := alu_add;
pc_source := from_branch;
branch_function := branch_eq;
a_source := A_FROM_PC;
b_source := B_FROM_IMMX4;
alu_function := ALU_ADD;
pc_source := FROM_BRANCH;
branch_function := BRANCH_EQ;
 
when "000101" => --BNE branch=r[rs]!=r[rt];
a_source := a_from_pc;
b_source := b_from_immX4;
alu_function := alu_add;
pc_source := from_branch;
branch_function := branch_ne;
a_source := A_FROM_PC;
b_source := B_FROM_IMMX4;
alu_function := ALU_ADD;
pc_source := FROM_BRANCH;
branch_function := BRANCH_NE;
 
when "000110" => --BLEZ branch=r[rs]<=0;
a_source := a_from_pc;
b_source := b_from_immX4;
alu_function := alu_add;
pc_source := from_branch;
branch_function := branch_lez;
a_source := A_FROM_PC;
b_source := b_FROM_IMMX4;
alu_function := ALU_ADD;
pc_source := FROM_BRANCH;
branch_function := BRANCH_LEZ;
 
when "000111" => --BGTZ branch=r[rs]>0;
a_source := a_from_pc;
b_source := b_from_immX4;
alu_function := alu_add;
pc_source := from_branch;
branch_function := branch_gtz;
a_source := A_FROM_PC;
b_source := B_FROM_IMMX4;
alu_function := ALU_ADD;
pc_source := FROM_BRANCH;
branch_function := BRANCH_GTZ;
 
when "001000" => --ADDI r[rt]=r[rs]+(short)imm;
b_source := b_from_signed_imm;
c_source := c_from_alu;
b_source := B_FROM_SIGNED_IMM;
c_source := C_FROM_ALU;
rd := rt;
alu_function := alu_add;
alu_function := ALU_ADD;
 
when "001001" => --ADDIU u[rt]=u[rs]+(short)imm;
b_source := b_from_signed_imm;
c_source := c_from_alu;
b_source := B_FROM_SIGNED_IMM;
c_source := C_FROM_ALU;
rd := rt;
alu_function := alu_add;
alu_function := ALU_ADD;
 
when "001010" => --SLTI r[rt]=r[rs]<(short)imm;
b_source := b_from_signed_imm;
c_source := c_from_alu;
b_source := B_FROM_SIGNED_IMM;
c_source := C_FROM_ALU;
rd := rt;
alu_function := alu_less_than_signed;
alu_function := ALU_LESS_THAN_SIGNED;
 
when "001011" => --SLTIU u[rt]=u[rs]<(unsigned long)(short)imm;
b_source := b_from_imm;
c_source := c_from_alu;
b_source := B_FROM_IMM;
c_source := C_FROM_ALU;
rd := rt;
alu_function := alu_less_than;
alu_function := ALU_LESS_THAN;
 
when "001100" => --ANDI r[rt]=r[rs]&imm;
b_source := b_from_imm;
c_source := c_from_alu;
b_source := B_FROM_IMM;
c_source := C_FROM_ALU;
rd := rt;
alu_function := alu_and;
alu_function := ALU_AND;
 
when "001101" => --ORI r[rt]=r[rs]|imm;
b_source := b_from_imm;
c_source := c_from_alu;
b_source := B_FROM_IMM;
c_source := C_FROM_ALU;
rd := rt;
alu_function := alu_or;
alu_function := ALU_OR;
 
when "001110" => --XORI r[rt]=r[rs]^imm;
b_source := b_from_imm;
c_source := c_from_alu;
b_source := B_FROM_IMM;
c_source := C_FROM_ALU;
rd := rt;
alu_function := alu_xor;
alu_function := ALU_XOR;
 
when "001111" => --LUI r[rt]=(imm<<16);
c_source := c_from_imm_shift16;
c_source := C_FROM_IMM_SHIFT16;
rd := rt;
 
when "010000" => --COP0
alu_function := alu_or;
c_source := c_from_alu;
alu_function := ALU_OR;
c_source := C_FROM_ALU;
if opcode(23) = '0' then --move from CP0
rs := '1' & opcode(15 downto 11);
rt := "000000";
307,96 → 346,111
rs := "000000";
rd(5) := '1';
end if;
 
when "010001" => --COP1
when "010010" => --COP2
when "010011" => --COP3
when "010100" => --BEQL lbranch=r[rs]==r[rt];
a_source := a_from_pc;
b_source := b_from_immX4;
alu_function := alu_add;
pc_source := from_lbranch;
branch_function := branch_eq;
a_source := A_FROM_PC;
b_source := B_FROM_IMMX4;
alu_function := ALU_ADD;
pc_source := FROM_LBRANCH;
branch_function := BRANCH_EQ;
 
when "010101" => --BNEL lbranch=r[rs]!=r[rt];
a_source := a_from_pc;
b_source := b_from_immX4;
alu_function := alu_add;
pc_source := from_lbranch;
branch_function := branch_ne;
a_source := A_FROM_PC;
b_source := B_FROM_IMMX4;
alu_function := ALU_ADD;
pc_source := FROM_LBRANCH;
branch_function := BRANCH_NE;
 
when "010110" => --BLEZL lbranch=r[rs]<=0;
a_source := a_from_pc;
b_source := b_from_immX4;
alu_function := alu_add;
pc_source := from_lbranch;
branch_function := branch_lez;
a_source := A_FROM_PC;
b_source := B_FROM_IMMX4;
alu_function := ALU_ADD;
pc_source := FROM_LBRANCH;
branch_function := BRANCH_LEZ;
 
when "010111" => --BGTZL lbranch=r[rs]>0;
a_source := a_from_pc;
b_source := b_from_immX4;
alu_function := alu_add;
pc_source := from_lbranch;
branch_function := branch_gtz;
a_source := A_FROM_PC;
b_source := B_FROM_IMMX4;
alu_function := ALU_ADD;
pc_source := FROM_LBRANCH;
branch_function := BRANCH_GTZ;
 
when "100000" => --LB r[rt]=*(signed char*)ptr;
a_source := a_from_reg_source;
b_source := b_from_signed_imm;
alu_function := alu_add;
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_SIGNED_IMM;
alu_function := ALU_ADD;
rd := rt;
c_source := c_from_memory;
mem_source := mem_read8s; --address=(short)imm+r[rs];
c_source := C_FROM_MEMORY;
mem_source := MEM_READ8S; --address=(short)imm+r[rs];
 
when "100001" => --LH r[rt]=*(signed short*)ptr;
a_source := a_from_reg_source;
b_source := b_from_signed_imm;
alu_function := alu_add;
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_SIGNED_IMM;
alu_function := ALU_ADD;
rd := rt;
c_source := c_from_memory;
mem_source := mem_read16s; --address=(short)imm+r[rs];
c_source := C_FROM_MEMORY;
mem_source := MEM_READ16S; --address=(short)imm+r[rs];
 
when "100010" => --LWL //Not Implemented
a_source := a_from_reg_source;
b_source := b_from_signed_imm;
alu_function := alu_add;
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_SIGNED_IMM;
alu_function := ALU_ADD;
rd := rt;
c_source := c_from_memory;
mem_source := mem_read32;
c_source := C_FROM_MEMORY;
mem_source := MEM_READ32;
 
when "100011" => --LW r[rt]=*(long*)ptr;
a_source := a_from_reg_source;
b_source := b_from_signed_imm;
alu_function := alu_add;
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_SIGNED_IMM;
alu_function := ALU_ADD;
rd := rt;
c_source := c_from_memory;
mem_source := mem_read32;
c_source := C_FROM_MEMORY;
mem_source := MEM_READ32;
 
when "100100" => --LBU r[rt]=*(unsigned char*)ptr;
a_source := a_from_reg_source;
b_source := b_from_signed_imm;
alu_function := alu_add;
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_SIGNED_IMM;
alu_function := ALU_ADD;
rd := rt;
c_source := c_from_memory;
mem_source := mem_read8; --address=(short)imm+r[rs];
c_source := C_FROM_MEMORY;
mem_source := MEM_READ8; --address=(short)imm+r[rs];
 
when "100101" => --LHU r[rt]=*(unsigned short*)ptr;
a_source := a_from_reg_source;
b_source := b_from_signed_imm;
alu_function := alu_add;
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_SIGNED_IMM;
alu_function := ALU_ADD;
rd := rt;
c_source := c_from_memory;
mem_source := mem_read16; --address=(short)imm+r[rs];
c_source := C_FROM_MEMORY;
mem_source := MEM_READ16; --address=(short)imm+r[rs];
 
when "100110" => --LWR //Not Implemented
when "101000" => --SB *(char*)ptr=(char)r[rt];
a_source := a_from_reg_source;
b_source := b_from_signed_imm;
alu_function := alu_add;
mem_source := mem_write8; --address=(short)imm+r[rs];
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_SIGNED_IMM;
alu_function := ALU_ADD;
mem_source := MEM_WRITE8; --address=(short)imm+r[rs];
 
when "101001" => --SH *(short*)ptr=(short)r[rt];
a_source := a_from_reg_source;
b_source := b_from_signed_imm;
alu_function := alu_add;
mem_source := mem_write16;
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_SIGNED_IMM;
alu_function := ALU_ADD;
mem_source := MEM_WRITE16;
 
when "101010" => --SWL //Not Implemented
a_source := a_from_reg_source;
b_source := b_from_signed_imm;
alu_function := alu_add;
mem_source := mem_write32; --address=(short)imm+r[rs];
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_SIGNED_IMM;
alu_function := ALU_ADD;
mem_source := MEM_WRITE32; --address=(short)imm+r[rs];
 
when "101011" => --SW *(long*)ptr=r[rt];
a_source := a_from_reg_source;
b_source := b_from_signed_imm;
alu_function := alu_add;
mem_source := mem_write32; --address=(short)imm+r[rs];
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_SIGNED_IMM;
alu_function := ALU_ADD;
mem_source := MEM_WRITE32; --address=(short)imm+r[rs];
 
when "101110" => --SWR //Not Implemented
when "101111" => --CACHE
when "110000" => --LL r[rt]=*(long*)ptr;
416,7 → 470,7
when others =>
end case;
 
if c_source = c_from_null then
if c_source = C_FROM_NULL then
rd := "000000";
end if;
 
424,15 → 478,15
rs := "111111"; --interrupt vector
rt := "000000";
rd := "101110"; --save PC in EPC
alu_function := alu_or;
shift_function := shift_nothing;
mult_function := mult_nothing;
branch_function := branch_yes;
a_source := a_from_reg_source;
b_source := b_from_reg_target;
c_source := c_from_pc;
pc_source := from_lbranch;
mem_source := mem_fetch;
alu_function := ALU_OR;
shift_function := SHIFT_NOTHING;
mult_function := MULT_NOTHING;
branch_function := BRANCH_YES;
a_source := A_FROM_REG_SOURCE;
b_source := B_FROM_REG_TARGET;
c_source := C_FROM_pc;
pc_source := FROM_LBRANCH;
mem_source := MEM_FETCH;
end if;
 
rs_index <= rs;
/trunk/vhdl/mult.vhd
44,6 → 44,7
generic(adder_type : string := "GENERIC";
mult_type : string := "GENERIC");
port(clk : in std_logic;
reset_in : in std_logic;
a, b : in std_logic_vector(31 downto 0);
mult_func : in mult_function_type;
c_mult : out std_logic_vector(31 downto 0);
52,9 → 53,6
 
architecture logic of mult is
 
-- type mult_function_type is (
-- mult_nothing, mult_read_lo, mult_read_hi, mult_write_lo,
-- mult_write_hi, mult_mult, mult_divide, mult_signed_divide);
signal do_mult_reg : std_logic;
signal do_signed_reg : std_logic;
signal count_reg : std_logic_vector(5 downto 0);
63,19 → 61,13
signal answer_reg : std_logic_vector(31 downto 0);
signal aa, bb : std_logic_vector(33 downto 0);
signal sum : std_logic_vector(33 downto 0);
signal sum2 : std_logic_vector(67 downto 0);
signal reg_a_times3 : std_logic_vector(33 downto 0);
signal sign_extend_sig : std_logic;
signal a_neg_sig : std_logic_vector(31 downto 0);
signal b_neg_sig : std_logic_vector(31 downto 0);
 
--Used in Xilinx tri-state area optimizated version
signal SUB_Y, A_PROCESSED, B_PROCESSED, A_REG, B_REG : std_logic_vector(31 downto 0);
signal DIV_Y, DIV_Y_IN, DIV_Y_IN_CALC, DIV_Y_IN_INIT, Y_IN, Y_IN2, MULT_Y, Y : std_logic_vector(63 downto 0) := (others => '0');
signal SAVE_Y, SAVE_DIV_Y, MULT_ND, MULT_RDY, DO_SIGNED, DIV_ND : std_logic;
signal DIV_COUNT, INVERT_A, INVERT_B, INVERT_Y, DIV_RDY : std_logic;
signal DIV_COUNTER : std_logic_vector(4 downto 0);
signal PAUSE_IN, SAVE_PAUSE, PAUSE : std_logic := '0';
signal MULT_RFD : std_logic;
signal a_temp_sig, a_neg_sig, b_neg_sig : std_logic_vector(31 downto 0);
signal a_temp_sig : std_logic_vector(31 downto 0);
signal b_temp_sig : std_logic_vector(63 downto 0);
signal a_msb, b_msb : std_logic;
signal answer_temp_sig : std_logic_vector(31 downto 0);
84,7 → 76,7
signal a_select : std_logic_vector(4 downto 0);
signal b_select : std_logic_vector(11 downto 0);
signal answer_select : std_logic_vector(2 downto 0);
 
begin
--sum = aa + bb
116,15 → 108,15
sign_extend_sig <= do_signed_reg and do_mult_reg;
-- Result
c_mult <= reg_b(31 downto 0) when mult_func=mult_read_lo else
reg_b(63 downto 32) when mult_func=mult_read_hi else
c_mult <= reg_b(31 downto 0) when mult_func = MULT_READ_LO else
reg_b(63 downto 32) when mult_func = MULT_READ_HI else
ZERO;
 
 
GENERIC_MULT: if MULT_TYPE="GENERIC" generate
GENERIC_MULT: if MULT_TYPE = "GENERIC" generate
--multiplication/division unit
mult_proc: process(clk, a, b, mult_func,
mult_proc: process(clk, reset_in, a, b, mult_func,
do_mult_reg, do_signed_reg, count_reg,
reg_a, reg_b, answer_reg, sum, reg_a_times3)
variable do_mult_temp : std_logic;
151,27 → 143,27
do_hi := '0';
 
case mult_func is
when mult_read_lo =>
when mult_read_hi =>
when MULT_READ_LO =>
when MULT_READ_HI =>
do_hi := '1';
when mult_write_lo =>
when MULT_WRITE_LO =>
do_write := '1';
when mult_write_hi =>
when MULT_WRITE_HI =>
do_write := '1';
do_hi := '1';
when mult_mult =>
when MULT_MULT =>
start := '1';
do_mult_temp := '1';
do_signed_temp := '0';
when mult_signed_mult =>
when MULT_SIGNED_MULT =>
start := '1';
do_mult_temp := '1';
do_signed_temp := '1';
when mult_divide =>
when MULT_DIVIDE =>
start := '1';
do_mult_temp := '0';
do_signed_temp := '0';
when mult_signed_divide =>
when MULT_SIGNED_DIVIDE =>
start := '1';
do_mult_temp := '0';
do_signed_temp := a(31) xor b(31);
183,12 → 175,12
answer_temp := ZERO;
if do_mult_temp = '0' then
b_temp(63) := '0';
if mult_func /= mult_signed_divide or a(31) = '0' then
if mult_func /= MULT_SIGNED_DIVIDE or a(31) = '0' then
a_temp := a;
else
a_temp := a_neg_sig;
end if;
if mult_func /= mult_signed_divide or b(31) = '0' then
if mult_func /= MULT_SIGNED_DIVIDE or b(31) = '0' then
b_temp(62 downto 31) := b;
else
b_temp(62 downto 31) := b_neg_sig;
266,7 → 258,15
end if;
end if;
 
if rising_edge(clk) then
if reset_in = '1' then
do_mult_reg <= '0';
do_signed_reg <= '0';
count_reg <= "000000";
reg_a <= ZERO;
reg_b <= ZERO & ZERO;
answer_reg <= ZERO;
reg_a_times3 <= "00" & ZERO;
elsif rising_edge(clk) then
do_mult_reg <= do_mult_temp;
do_signed_reg <= do_signed_temp;
count_reg <= count_temp;
287,6 → 287,18
end process;
 
--Only used in Xilinx tri-state area optimizated version
a_temp_sig <= ZERO;
b_temp_sig <= ZERO & ZERO;
a_msb <= '0';
b_msb <= '0';
answer_temp_sig <= ZERO;
aa_select <= "0000";
bb_select <= "00";
a_select <= "00000";
b_select <= ZERO(11 downto 0);
answer_select <= "000";
 
end generate;
 
 
319,27 → 331,27
answer_select <= (others => '0');
case mult_func is
when mult_read_lo =>
when mult_read_hi =>
when MULT_READ_LO =>
when MULT_READ_HI =>
do_hi := '1';
when mult_write_lo =>
when MULT_WRITE_LO =>
do_write := '1';
when mult_write_hi =>
when MULT_WRITE_HI =>
do_write := '1';
do_hi := '1';
when mult_mult =>
when MULT_MULT =>
start := '1';
do_mult_temp := '1';
do_signed_temp := '0';
when mult_signed_mult =>
when MULT_SIGNED_MULT =>
start := '1';
do_mult_temp := '1';
do_signed_temp := '1';
when mult_divide =>
when MULT_DIVIDE =>
start := '1';
do_mult_temp := '0';
do_signed_temp := '0';
when mult_signed_divide =>
when MULT_SIGNED_DIVIDE =>
start := '1';
do_mult_temp := '0';
do_signed_temp := a(31) xor b(31);
352,7 → 364,7
--answer_temp := ZERO;
if do_mult_temp = '0' then
--b_temp(63) := '0';
if mult_func /= mult_signed_divide or a(31) = '0' then
if mult_func /= MULT_SIGNED_DIVIDE or a(31) = '0' then
a_select(0) <= '1';
--a_temp := a;
else
359,7 → 371,7
a_select(1) <= '1';
--a_temp := a_neg;
end if;
if mult_func /= mult_signed_divide or b(31) = '0' then
if mult_func /= MULT_SIGNED_DIVIDE or b(31) = '0' then
b_select(0) <= '1';
--b_temp(62 downto 31) := b;
else
461,17 → 473,25
end if;
end if;
 
if rising_edge(clk) then
do_mult_reg <= do_mult_temp;
do_signed_reg <= do_signed_temp;
count_reg <= count_temp;
reg_a <= a_temp_sig;
reg_b <= b_temp_sig;
answer_reg <= answer_temp_sig;
if start = '1' then
reg_a_times3 <= ((a_temp_sig(31) and do_signed_temp) & a_temp_sig & '0') +
((a_temp_sig(31) and do_signed_temp) & (a_temp_sig(31) and do_signed_temp) & a_temp_sig);
end if;
if reset_in = '1' then
do_mult_reg <= '0';
do_signed_reg <= '0';
count_reg <= "000000";
reg_a <= ZERO;
reg_b <= ZERO & ZERO;
answer_reg <= ZERO;
reg_a_times3 <= "00" & ZERO;
elsif rising_edge(clk) then
do_mult_reg <= do_mult_temp;
do_signed_reg <= do_signed_temp;
count_reg <= count_temp;
reg_a <= a_temp_sig;
reg_b <= b_temp_sig;
answer_reg <= answer_temp_sig;
if start = '1' then
reg_a_times3 <= ((a_temp_sig(31) and do_signed_temp) & a_temp_sig & '0') +
((a_temp_sig(31) and do_signed_temp) & (a_temp_sig(31) and do_signed_temp) & a_temp_sig);
end if;
end if;
 
if count_reg(5) = '0' and mult_func/= mult_nothing and start = '0' then
/trunk/vhdl/mlite_cpu.vhd
147,7 → 147,7
pause_any <= (mem_pause or pause_ctrl) or (pause_mult or pause_pipeline);
pause_non_ctrl <= (mem_pause or pause_mult) or pause_pipeline;
pause_bank <= (mem_pause or pause_ctrl or pause_mult) and not pause_pipeline;
nullify_op <= '1' when (pc_source = from_lbranch and take_branch = '0')
nullify_op <= '1' when (pc_source = FROM_LBRANCH and take_branch = '0')
or intr_signal = '1'
else '0';
c_bus <= c_alu or c_shift or c_mult;
285,6 → 285,7
mult_type => mult_type)
port map (
clk => clk,
reset_in => reset,
a => a_busD,
b => b_busD,
mult_func => mult_funcD,
/trunk/vhdl/alu.vhd
23,30 → 23,26
end; --alu
 
architecture logic of alu is
-- type alu_function_type is (alu_nothing, alu_add, alu_subtract,
-- alu_less_than, alu_less_than_signed,
-- alu_or, alu_and, alu_xor, alu_nor);
signal aa, bb, sum : std_logic_vector(32 downto 0);
signal do_add : std_logic;
signal sign_ext : std_logic;
begin
 
do_add <= '1' when alu_function = alu_add else '0';
sign_ext <= '0' when alu_function = alu_less_than else '1';
do_add <= '1' when alu_function = ALU_ADD else '0';
sign_ext <= '0' when alu_function = ALU_LESS_THAN else '1';
aa <= (a_in(31) and sign_ext) & a_in;
bb <= (b_in(31) and sign_ext) & b_in;
 
-- synthesis translate_off
GENERIC_ALU: if alu_type="GENERIC" generate
GENERIC_ALU: if alu_type = "GENERIC" generate
-- synthesis translate_on
 
c_alu <= sum(31 downto 0) when alu_function=alu_add or alu_function=alu_subtract else
ZERO(31 downto 1) & sum(32) when alu_function=alu_less_than or alu_function=alu_less_than_signed else
a_in or b_in when alu_function=alu_or else
a_in and b_in when alu_function=alu_and else
a_in xor b_in when alu_function=alu_xor else
a_in nor b_in when alu_function=alu_nor else
c_alu <= sum(31 downto 0) when alu_function=ALU_ADD or alu_function=ALU_SUBTRACT else
ZERO(31 downto 1) & sum(32) when alu_function=ALU_LESS_THAN or alu_function=ALU_LESS_THAN_SIGNED else
a_in or b_in when alu_function=ALU_OR else
a_in and b_in when alu_function=ALU_AND else
a_in xor b_in when alu_function=ALU_XOR else
a_in nor b_in when alu_function=ALU_NOR else
ZERO;
 
-- synthesis translate_off
57,13 → 53,13
 
AREA_OPTIMIZED_ALU: if alu_type="AREA_OPTIMIZED" generate
c_alu <= sum(31 downto 0) when alu_function=alu_add or alu_function=alu_subtract else (others => 'Z');
c_alu <= ZERO(31 downto 1) & sum(32) when alu_function=alu_less_than or alu_function=alu_less_than_signed else (others => 'Z');
c_alu <= a_in or b_in when alu_function=alu_or else (others => 'Z');
c_alu <= a_in and b_in when alu_function=alu_and else (others => 'Z');
c_alu <= a_in xor b_in when alu_function=alu_xor else (others => 'Z');
c_alu <= a_in nor b_in when alu_function=alu_nor else (others => 'Z');
c_alu <= ZERO when alu_function=alu_nothing else (others => 'Z');
c_alu <= sum(31 downto 0) when alu_function=ALU_ADD or alu_function=ALU_SUBTRACT else (others => 'Z');
c_alu <= ZERO(31 downto 1) & sum(32) when alu_function=ALU_LESS_THAN or alu_function=ALU_LESS_THAN_SIGNED else (others => 'Z');
c_alu <= a_in or b_in when alu_function=ALU_OR else (others => 'Z');
c_alu <= a_in and b_in when alu_function=ALU_AND else (others => 'Z');
c_alu <= a_in xor b_in when alu_function=ALU_XOR else (others => 'Z');
c_alu <= a_in nor b_in when alu_function=ALU_NOR else (others => 'Z');
c_alu <= ZERO when alu_function=ALU_NOTHING else (others => 'Z');
end generate;
/trunk/vhdl/bus_mux.vhd
42,21 → 42,18
 
architecture logic of bus_mux is
begin
-- type a_source_type is (a_from_reg_source, a_from_imm10_6);
-- type b_source_type is (b_from_reg_target, b_from_imm, b_from_signed_imm);
-- type c_source_type is (c_from_null, c_from_alu, c_from_shift,
-- c_from_mult, c_from_memory, c_from_pc, c_from_imm_shift16,
-- c_from_reg_source_nez, c_from_reg_source_eqz);
 
amux: process(reg_source, imm_in, a_mux, c_pc)
begin
case a_mux is
when a_from_reg_source =>
when A_FROM_REG_SOURCE =>
a_out <= reg_source;
when a_from_imm10_6 =>
a_out(31 downto 5) <= ZERO(31 downto 5);
a_out(4 downto 0) <= imm_in(10 downto 6);
when others => --a_from_pc
when A_FROM_IMM10_6 =>
a_out <= ZERO(31 downto 5) & imm_in(10 downto 6);
when A_FROM_PC =>
a_out <= c_pc;
when others =>
a_out <= c_pc;
end case;
end process;
 
63,11 → 60,11
bmux: process(reg_target, imm_in, b_mux)
begin
case b_mux is
when b_from_reg_target =>
when B_FROM_REG_TARGET =>
b_out <= reg_target;
when b_from_imm =>
when B_FROM_IMM =>
b_out <= ZERO(31 downto 16) & imm_in;
when b_from_signed_imm =>
when B_FROM_SIGNED_IMM =>
if imm_in(15) = '0' then
b_out(31 downto 16) <= ZERO(31 downto 16);
else
74,7 → 71,7
b_out(31 downto 16) <= "1111111111111111";
end if;
b_out(15 downto 0) <= imm_in;
when others => --b_from_immX4
when B_FROM_IMMX4 =>
if imm_in(15) = '0' then
b_out(31 downto 18) <= "00000000000000";
else
81,6 → 78,8
b_out(31 downto 18) <= "11111111111111";
end if;
b_out(17 downto 0) <= imm_in & "00";
when others =>
b_out <= reg_target;
end case;
end process;
 
87,20 → 86,16
cmux: process(c_bus, c_memory, c_pc, c_pc_plus4, imm_in, c_mux)
begin
case c_mux is
when c_from_alu => -- | c_from_shift | c_from_mult =>
when C_FROM_ALU => -- | C_FROM_SHIFT | C_FROM_MULT =>
reg_dest_out <= c_bus;
when c_from_memory =>
when C_FROM_MEMORY =>
reg_dest_out <= c_memory;
when c_from_pc =>
when C_FROM_PC =>
reg_dest_out <= c_pc(31 downto 3) & "000"; --backup one opcode
when c_from_pc_plus4 =>
when C_FROM_PC_PLUS4 =>
reg_dest_out <= c_pc_plus4;
when c_from_imm_shift16 =>
when C_FROM_IMM_SHIFT16 =>
reg_dest_out <= imm_in & ZERO(15 downto 0);
-- when from_reg_source_nez =>
--????
-- when from_reg_source_eqz =>
--????
when others =>
reg_dest_out <= c_bus;
end case;
115,19 → 110,19
is_equal := '0';
end if;
case branch_func is
when branch_ltz =>
when BRANCH_LTZ =>
take_branch <= reg_source(31);
when branch_lez =>
when BRANCH_LEZ =>
take_branch <= reg_source(31) or is_equal;
when branch_eq =>
when BRANCH_EQ =>
take_branch <= is_equal;
when branch_ne =>
when BRANCH_NE =>
take_branch <= not is_equal;
when branch_gez =>
when BRANCH_GEZ =>
take_branch <= not reg_source(31);
when branch_gtz =>
when BRANCH_GTZ =>
take_branch <= not reg_source(31) and not is_equal;
when branch_yes =>
when BRANCH_YES =>
take_branch <= '1';
when others =>
take_branch <= is_equal;

powered by: WebSVN 2.1.0

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