<commit_before>library IEEE;
use IEEE.std_logic_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

library work;
use work.constants.all;

entity bus_wb8 is
	Port(
		-- wired to CPU core
		I_en: in std_logic;
		I_op: in memops_t; -- memory opcodes
		I_iaddr: in std_logic_vector(31 downto 0); -- instruction address, provided by PCU
		I_daddr: in std_logic_vector(31 downto 0); -- data address, provided by ALU
		I_data: in std_logic_vector(31 downto 0); -- data to be stored on write ops
		I_mem_imem: in std_logic := '0'; -- denotes if instruction memory is accessed (signal from control unit)
		O_data : out std_logic_vector(31 downto 0);
		O_busy: out std_logic := '0';

		-- wired to outside world, RAM, devices etc.
		-- naming of signals taken from Wishbone B4 spec
		CLK_I: in std_logic := '0';
		ACK_I: in std_logic := '0';
		DAT_I: in std_logic_vector(7 downto 0);
		RST_I: in std_logic := '0';
		ADR_O: out std_logic_vector(31 downto 0);
		DAT_O: out std_logic_vector(7 downto 0);
		CYC_O: out std_logic := '0';
		STB_O: out std_logic := '0';
		WE_O: out std_logic := '0'
	
	);

end bus_wb8;

architecture Behavioral of bus_wb8 is
	type control_states is (IDLE, READ_START, READ_FINISH, WRITE_START, WRITE_FINISH);
	
begin
	process(CLK_I)
		variable state: control_states := IDLE;
		variable adr: std_logic_vector(31 downto 0) := X"00000000";
		variable buf: std_logic_vector(31 downto 0) := X"00000000";
		variable byte, byte_target: integer range 0 to 3;
		variable imem, zeroextend: std_logic := '0';
	begin

		if rising_edge(CLK_I) then
		
			if I_en = '1' then
				--------------------------------------
				-- when idle, evaluate requested memop
				--------------------------------------
				if state = IDLE then
					O_busy <= '1';
					zeroextend := '0';
					imem := I_mem_imem;
					byte := 0; -- start at byte 0
				
					case I_op is
						when MEMOP_READW =>
							byte_target := 3; -- read 4 bytes
							state := READ_START;
						
						when MEMOP_READH =>
							byte_target := 1; -- read 2 bytes
							state := READ_START;
							
						when MEMOP_READHU =>
							byte_target := 1; -- read 2 bytes
							zeroextend := '1';
							state := READ_START;
						
						when MEMOP_READB =>
							byte_target := 0; -- read 1 byte
							state := READ_START;
							
						when MEMOP_READBU =>
							byte_target := 0; -- read 1 byte
							zeroextend := '1';
							state := READ_START;
						
						when MEMOP_WRITEW =>
							byte_target := 3; -- write 4 bytes
							state := WRITE_START;
							
						when MEMOP_WRITEH =>
							byte_target := 1; -- write 2 bytes
							state := WRITE_START;
						
						when MEMOP_WRITEB =>
							byte_target := 0; -- write 1 byte
							state := WRITE_START;
						
						when MEMOP_NOP =>
							null;
							
					end case;
				end if;
			
				-- compute memory address
				if imem = '1' then
					-- read from instruction memory
					adr := I_iaddr;
				else
					-- read from data memory/devices
					adr := I_daddr;
				end if;
				ADR_O <= std_logic_vector(unsigned(adr) + byte);
			
				-----------------------------------
				-- execute read or write operations
				-----------------------------------
				case state is
					when READ_START =>
						WE_O <= '0';
						CYC_O <= '1';
						STB_O <= '1';
						state := READ_FINISH;
				
					when READ_FINISH =>
						if ACK_I = '1' then
							STB_O <= '0';

							case byte is
								when 0 =>
									if zeroextend = '1' then
										buf := X"000000" & DAT_I;
									else
										buf := std_logic_vector(resize(signed(DAT_I), buf'length));
									end if;
								when 1 =>
									if zeroextend = '1' then
										buf := X"0000" & DAT_I & buf(7 downto 0);
									else
										buf := std_logic_vector(resize(signed(DAT_I & buf(7 downto 0)), buf'length));
									end if;
								when 2 =>
									buf := std_logic_vector(resize(signed(DAT_I & buf(15 downto 0)), buf'length));
								when 3 =>
									buf := DAT_I & buf(23 downto 0);
							end case;
						
							if byte < byte_target then
								-- we didn't read all bytes yet
								byte := byte + 1;<commit_msg>bus unit: Do not zero- or sign-extend 24-bit reads (because those only happen as part of 32-bit reads, meaning the extensions will be overwritten). Cuts down on the logic.<commit_after>library IEEE;
use IEEE.std_logic_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

library work;
use work.constants.all;

entity bus_wb8 is
	Port(
		-- wired to CPU core
		I_en: in std_logic;
		I_op: in memops_t; -- memory opcodes
		I_iaddr: in std_logic_vector(31 downto 0); -- instruction address, provided by PCU
		I_daddr: in std_logic_vector(31 downto 0); -- data address, provided by ALU
		I_data: in std_logic_vector(31 downto 0); -- data to be stored on write ops
		I_mem_imem: in std_logic := '0'; -- denotes if instruction memory is accessed (signal from control unit)
		O_data : out std_logic_vector(31 downto 0);
		O_busy: out std_logic := '0';

		-- wired to outside world, RAM, devices etc.
		-- naming of signals taken from Wishbone B4 spec
		CLK_I: in std_logic := '0';
		ACK_I: in std_logic := '0';
		DAT_I: in std_logic_vector(7 downto 0);
		RST_I: in std_logic := '0';
		ADR_O: out std_logic_vector(31 downto 0);
		DAT_O: out std_logic_vector(7 downto 0);
		CYC_O: out std_logic := '0';
		STB_O: out std_logic := '0';
		WE_O: out std_logic := '0'
	
	);

end bus_wb8;

architecture Behavioral of bus_wb8 is
	type control_states is (IDLE, READ_START, READ_FINISH, WRITE_START, WRITE_FINISH);
	
begin
	process(CLK_I)
		variable state: control_states := IDLE;
		variable adr: std_logic_vector(31 downto 0) := X"00000000";
		variable buf: std_logic_vector(31 downto 0) := X"00000000";
		variable byte, byte_target: integer range 0 to 3;
		variable imem, zeroextend: std_logic := '0';
	begin

		if rising_edge(CLK_I) then
		
			if I_en = '1' then
				--------------------------------------
				-- when idle, evaluate requested memop
				--------------------------------------
				if state = IDLE then
					O_busy <= '1';
					zeroextend := '0';
					imem := I_mem_imem;
					byte := 0; -- start at byte 0
				
					case I_op is
						when MEMOP_READW =>
							byte_target := 3; -- read 4 bytes
							state := READ_START;
						
						when MEMOP_READH =>
							byte_target := 1; -- read 2 bytes
							state := READ_START;
							
						when MEMOP_READHU =>
							byte_target := 1; -- read 2 bytes
							zeroextend := '1';
							state := READ_START;
						
						when MEMOP_READB =>
							byte_target := 0; -- read 1 byte
							state := READ_START;
							
						when MEMOP_READBU =>
							byte_target := 0; -- read 1 byte
							zeroextend := '1';
							state := READ_START;
						
						when MEMOP_WRITEW =>
							byte_target := 3; -- write 4 bytes
							state := WRITE_START;
							
						when MEMOP_WRITEH =>
							byte_target := 1; -- write 2 bytes
							state := WRITE_START;
						
						when MEMOP_WRITEB =>
							byte_target := 0; -- write 1 byte
							state := WRITE_START;
						
						when MEMOP_NOP =>
							null;
							
					end case;
				end if;
			
				-- compute memory address
				if imem = '1' then
					-- read from instruction memory
					adr := I_iaddr;
				else
					-- read from data memory/devices
					adr := I_daddr;
				end if;
				ADR_O <= std_logic_vector(unsigned(adr) + byte);
			
				-----------------------------------
				-- execute read or write operations
				-----------------------------------
				case state is
					when READ_START =>
						WE_O <= '0';
						CYC_O <= '1';
						STB_O <= '1';
						state := READ_FINISH;
				
					when READ_FINISH =>
						if ACK_I = '1' then
							STB_O <= '0';

							case byte is
								when 0 =>
									if zeroextend = '1' then
										buf := X"000000" & DAT_I;
									else
										buf := std_logic_vector(resize(signed(DAT_I), buf'length));
									end if;
								when 1 =>
									if zeroextend = '1' then
										buf := X"0000" & DAT_I & buf(7 downto 0);
									else
										buf := std_logic_vector(resize(signed(DAT_I & buf(7 downto 0)), buf'length));
									end if;
								when 2 =>
									buf(23 downto 16) := DAT_I;
								when 3 =>
									buf(31 downto 24) := DAT_I;
							end case;
						
							if byte < byte_target then
								-- we didn't read all bytes yet
								byte := byte + 1;
{'fraction_non_alphanumeric': 0.13687755592975703, 'fraction_numerical': 0.02862641327880683, 'mean_word_length': 1.9175438596491228, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 33, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 4, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2454083', 'n_tokens_mistral': 4048, 'n_tokens_neox': 2702, 'n_words': 856}