forked from cores/microwatt
				
			Add arrays for ASIC flow
Add VHDL wrappers and verilog behaviourals for the cache_ram, register_file and main_bram arrays. Signed-off-by: Anton Blanchard <anton@linux.ibm.com>asic-3
							parent
							
								
									ef641dcc28
								
							
						
					
					
						commit
						537a0aac1d
					
				@ -0,0 +1,24 @@
 | 
			
		||||
module Microwatt_FP_DFFRFile (
 | 
			
		||||
`ifdef USE_POWER_PINS
 | 
			
		||||
    inout VPWR,
 | 
			
		||||
    inout VGND,
 | 
			
		||||
`endif
 | 
			
		||||
    input [6:0]   R1, R2, R3, RW,
 | 
			
		||||
    input [63:0]  DW,
 | 
			
		||||
    output [63:0] D1, D2, D3,
 | 
			
		||||
    input CLK,
 | 
			
		||||
    input WE
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
    reg [63:0] registers[0:79];
 | 
			
		||||
 | 
			
		||||
    assign D1 = registers[R1];
 | 
			
		||||
    assign D2 = registers[R2];
 | 
			
		||||
    assign D3 = registers[R3];
 | 
			
		||||
 | 
			
		||||
    always @(posedge CLK) begin
 | 
			
		||||
        if (WE)
 | 
			
		||||
            registers[RW] <= DW;
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
@ -0,0 +1,40 @@
 | 
			
		||||
module RAM32_1RW1R #(
 | 
			
		||||
    parameter BITS=5
 | 
			
		||||
) (
 | 
			
		||||
`ifdef USE_POWER_PINS
 | 
			
		||||
    inout VPWR,
 | 
			
		||||
    inout VGND,
 | 
			
		||||
`endif
 | 
			
		||||
    input CLK,
 | 
			
		||||
 | 
			
		||||
    input EN0,
 | 
			
		||||
    input [BITS-1:0] A0,
 | 
			
		||||
    input [7:0] WE0,
 | 
			
		||||
    input [63:0] Di0,
 | 
			
		||||
    output reg [63:0] Do0,
 | 
			
		||||
 | 
			
		||||
    input EN1,
 | 
			
		||||
    input [BITS-1:0] A1,
 | 
			
		||||
    output reg [63:0] Do1
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
    reg [63:0] RAM[2**BITS-1:0];
 | 
			
		||||
 | 
			
		||||
    always @(posedge CLK) begin
 | 
			
		||||
        if (EN1)
 | 
			
		||||
            Do1 <= RAM[A1];
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    generate
 | 
			
		||||
        genvar i;
 | 
			
		||||
        for (i=0; i<8; i=i+1) begin: BYTE
 | 
			
		||||
            always @(posedge CLK) begin
 | 
			
		||||
                if (EN0) begin
 | 
			
		||||
                    if (WE0[i])
 | 
			
		||||
                        RAM[A0][i*8+7:i*8] <= Di0[i*8+7:i*8];
 | 
			
		||||
                end
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
    endgenerate
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
@ -0,0 +1,42 @@
 | 
			
		||||
module RAM512 #(
 | 
			
		||||
    parameter BITS=9,
 | 
			
		||||
    parameter FILENAME="firmware.hex"
 | 
			
		||||
) (
 | 
			
		||||
`ifdef USE_POWER_PINS
 | 
			
		||||
    inout VPWR,
 | 
			
		||||
    inout VGND,
 | 
			
		||||
`endif
 | 
			
		||||
    input CLK,
 | 
			
		||||
    input [7:0] WE0,
 | 
			
		||||
    input EN0,
 | 
			
		||||
    input [63:0] Di0,
 | 
			
		||||
    output reg [63:0] Do0,
 | 
			
		||||
    input [BITS-1:0] A0
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
    reg [63:0] RAM[2**BITS-1:0];
 | 
			
		||||
 | 
			
		||||
    always @(posedge CLK) begin
 | 
			
		||||
        if (EN0)
 | 
			
		||||
            Do0 <= RAM[A0];
 | 
			
		||||
        else
 | 
			
		||||
            Do0 <= 64'b0;
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    generate
 | 
			
		||||
        genvar i;
 | 
			
		||||
        for (i=0; i<8; i=i+1) begin: BYTE
 | 
			
		||||
            always @(posedge CLK) begin
 | 
			
		||||
                if (EN0) begin
 | 
			
		||||
                    if (WE0[i])
 | 
			
		||||
                        RAM[A0][i*8+7:i*8] <= Di0[i*8+7:i*8];
 | 
			
		||||
                end
 | 
			
		||||
            end
 | 
			
		||||
        end
 | 
			
		||||
    endgenerate
 | 
			
		||||
 | 
			
		||||
initial begin
 | 
			
		||||
    $readmemh(FILENAME, RAM);
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
@ -0,0 +1,25 @@
 | 
			
		||||
module multiply_add_64x64
 | 
			
		||||
#(
 | 
			
		||||
    parameter BITS=64
 | 
			
		||||
) (
 | 
			
		||||
`ifdef USE_POWER_PINS
 | 
			
		||||
    inout VPWR,
 | 
			
		||||
    inout VGND,
 | 
			
		||||
`endif
 | 
			
		||||
    input clk,
 | 
			
		||||
    input [BITS-1:0] a,
 | 
			
		||||
    input [BITS-1:0] b,
 | 
			
		||||
    input [BITS*2-1:0] c,
 | 
			
		||||
    output [BITS*2-1:0] o
 | 
			
		||||
);
 | 
			
		||||
    reg [BITS*2-1:0] o_tmp[3:0];
 | 
			
		||||
 | 
			
		||||
    always @(posedge clk) begin
 | 
			
		||||
        o_tmp[3] = o_tmp[2];
 | 
			
		||||
        o_tmp[2] = o_tmp[1];
 | 
			
		||||
        o_tmp[1] = o_tmp[0];
 | 
			
		||||
	o_tmp[0] = (a * b) + c;
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    assign o = o_tmp[3];
 | 
			
		||||
endmodule
 | 
			
		||||
@ -0,0 +1,99 @@
 | 
			
		||||
library ieee;
 | 
			
		||||
use ieee.std_logic_1164.all;
 | 
			
		||||
use ieee.numeric_std.all;
 | 
			
		||||
use ieee.math_real.all;
 | 
			
		||||
 | 
			
		||||
entity cache_ram is
 | 
			
		||||
    generic(
 | 
			
		||||
        ROW_BITS : integer := 5;
 | 
			
		||||
        WIDTH    : integer := 64;
 | 
			
		||||
        TRACE    : boolean := false;
 | 
			
		||||
        ADD_BUF  : boolean := false
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
    port(
 | 
			
		||||
        clk     : in std_logic;
 | 
			
		||||
 | 
			
		||||
        rd_en   : in std_logic;
 | 
			
		||||
        rd_addr : in std_logic_vector(ROW_BITS - 1 downto 0);
 | 
			
		||||
        rd_data : out std_logic_vector(WIDTH - 1 downto 0);
 | 
			
		||||
 | 
			
		||||
        wr_sel  : in std_logic_vector(WIDTH/8 - 1 downto 0);
 | 
			
		||||
        wr_addr : in std_logic_vector(ROW_BITS - 1 downto 0);
 | 
			
		||||
        wr_data : in std_logic_vector(WIDTH - 1 downto 0)
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
end cache_ram;
 | 
			
		||||
 | 
			
		||||
architecture rtl of cache_ram is
 | 
			
		||||
    component RAM32_1RW1R port(
 | 
			
		||||
        CLK     : in std_logic;
 | 
			
		||||
 | 
			
		||||
        EN0     : in std_logic;
 | 
			
		||||
        A0      : in std_logic_vector(4 downto 0);
 | 
			
		||||
        WE0     : in std_logic_vector(7 downto 0);
 | 
			
		||||
        Di0     : in std_logic_vector(63 downto 0);
 | 
			
		||||
        Do0     : out std_logic_vector(63 downto 0);
 | 
			
		||||
 | 
			
		||||
        EN1     : in std_logic;
 | 
			
		||||
        A1      : in std_logic_vector(4 downto 0);
 | 
			
		||||
        Do1     : out std_logic_vector(63 downto 0)
 | 
			
		||||
        );
 | 
			
		||||
    end component;
 | 
			
		||||
 | 
			
		||||
    signal wr_enable: std_logic;
 | 
			
		||||
    signal rd_data0_tmp : std_logic_vector(WIDTH - 1 downto 0);
 | 
			
		||||
    signal rd_data0_saved : std_logic_vector(WIDTH - 1 downto 0);
 | 
			
		||||
    signal rd_data0 : std_logic_vector(WIDTH - 1 downto 0);
 | 
			
		||||
    signal rd_en_prev: std_ulogic;
 | 
			
		||||
begin
 | 
			
		||||
    assert (ROW_BITS = 5)  report "ROW_BITS must be 5" severity FAILURE;
 | 
			
		||||
    assert (WIDTH = 64)    report "Must be 64 bit" severity FAILURE;
 | 
			
		||||
    assert (TRACE = false) report "Trace not supported" severity FAILURE;
 | 
			
		||||
 | 
			
		||||
    wr_enable <= or(wr_sel);
 | 
			
		||||
 | 
			
		||||
    cache_ram_0 : RAM32_1RW1R
 | 
			
		||||
        port map (
 | 
			
		||||
            CLK     => clk,
 | 
			
		||||
 | 
			
		||||
            EN0     => wr_enable,
 | 
			
		||||
            A0      => wr_addr,
 | 
			
		||||
            WE0     => wr_sel,
 | 
			
		||||
            Di0     => wr_data,
 | 
			
		||||
            Do0     => open,
 | 
			
		||||
 | 
			
		||||
            EN1     => rd_en,
 | 
			
		||||
            A1      => rd_addr,
 | 
			
		||||
            Do1     => rd_data0_tmp
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
    -- The caches rely on cache_ram latching the last read. Handle it here
 | 
			
		||||
    -- for now.
 | 
			
		||||
    process(clk)
 | 
			
		||||
    begin
 | 
			
		||||
        if rising_edge(clk) then
 | 
			
		||||
            rd_en_prev <= rd_en;
 | 
			
		||||
            if rd_en_prev = '1' then
 | 
			
		||||
                rd_data0_saved <= rd_data0_tmp;
 | 
			
		||||
            end if;
 | 
			
		||||
        end if;
 | 
			
		||||
    end process;
 | 
			
		||||
    rd_data0 <= rd_data0_tmp when rd_en_prev = '1' else rd_data0_saved;
 | 
			
		||||
 | 
			
		||||
    buf: if ADD_BUF generate
 | 
			
		||||
    begin
 | 
			
		||||
        process(clk)
 | 
			
		||||
        begin
 | 
			
		||||
            if rising_edge(clk) then
 | 
			
		||||
                rd_data <= rd_data0;
 | 
			
		||||
            end if;
 | 
			
		||||
        end process;
 | 
			
		||||
    end generate;
 | 
			
		||||
 | 
			
		||||
    nobuf: if not ADD_BUF generate
 | 
			
		||||
    begin
 | 
			
		||||
        rd_data <= rd_data0;
 | 
			
		||||
    end generate;
 | 
			
		||||
 | 
			
		||||
end architecture rtl;
 | 
			
		||||
@ -0,0 +1,63 @@
 | 
			
		||||
library ieee;
 | 
			
		||||
use ieee.std_logic_1164.all;
 | 
			
		||||
 | 
			
		||||
library work;
 | 
			
		||||
 | 
			
		||||
entity main_bram is
 | 
			
		||||
    generic(
 | 
			
		||||
        WIDTH        : natural := 64;
 | 
			
		||||
        HEIGHT_BITS  : natural := 11;
 | 
			
		||||
        MEMORY_SIZE  : natural := (8*1024);
 | 
			
		||||
        RAM_INIT_FILE : string
 | 
			
		||||
        );
 | 
			
		||||
    port(
 | 
			
		||||
        clk  : in std_logic;
 | 
			
		||||
        addr : in std_logic_vector(HEIGHT_BITS - 1 downto 0) ;
 | 
			
		||||
        din  : in std_logic_vector(WIDTH-1 downto 0);
 | 
			
		||||
        dout : out std_logic_vector(WIDTH-1 downto 0);
 | 
			
		||||
        sel  : in std_logic_vector((WIDTH/8)-1 downto 0);
 | 
			
		||||
        re   : in std_ulogic;
 | 
			
		||||
        we   : in std_ulogic
 | 
			
		||||
        );
 | 
			
		||||
end entity main_bram;
 | 
			
		||||
 | 
			
		||||
architecture behaviour of main_bram is
 | 
			
		||||
    component RAM512 port (
 | 
			
		||||
        CLK : in std_ulogic;
 | 
			
		||||
        WE0 : in std_ulogic_vector(7 downto 0);
 | 
			
		||||
        EN0 : in std_ulogic;
 | 
			
		||||
        Di0 : in std_ulogic_vector(63 downto 0);
 | 
			
		||||
        Do0 : out std_ulogic_vector(63 downto 0);
 | 
			
		||||
        A0  : in std_ulogic_vector(8 downto 0)
 | 
			
		||||
    );
 | 
			
		||||
    end component;
 | 
			
		||||
 | 
			
		||||
    signal sel_qual: std_ulogic_vector((WIDTH/8)-1 downto 0);
 | 
			
		||||
 | 
			
		||||
    signal obuf : std_logic_vector(WIDTH-1 downto 0);
 | 
			
		||||
begin
 | 
			
		||||
    assert (WIDTH = 64)         report "Must be 64 bit" severity FAILURE;
 | 
			
		||||
    -- Do we have a log2 round up issue here?
 | 
			
		||||
    assert (HEIGHT_BITS = 10)   report "HEIGHT_BITS must be 10" severity FAILURE;
 | 
			
		||||
    assert (MEMORY_SIZE = 4096) report "MEMORY_SIZE must be 4096" severity FAILURE;
 | 
			
		||||
 | 
			
		||||
    sel_qual <= sel when we = '1' else (others => '0');
 | 
			
		||||
 | 
			
		||||
    memory_0 : RAM512
 | 
			
		||||
        port map (
 | 
			
		||||
            CLK  => clk,
 | 
			
		||||
            WE0  => sel_qual(7 downto 0),
 | 
			
		||||
            EN0  => re or we,
 | 
			
		||||
            Di0  => din(63 downto 0),
 | 
			
		||||
            Do0  => obuf(63 downto 0),
 | 
			
		||||
            A0   => addr(8 downto 0)
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
    -- The wishbone BRAM wrapper assumes a 1 cycle delay
 | 
			
		||||
    memory_read_buffer: process(clk)
 | 
			
		||||
    begin
 | 
			
		||||
        if rising_edge(clk) then
 | 
			
		||||
            dout <= obuf;
 | 
			
		||||
        end if;
 | 
			
		||||
    end process;
 | 
			
		||||
end architecture behaviour;
 | 
			
		||||
@ -0,0 +1,103 @@
 | 
			
		||||
library ieee;
 | 
			
		||||
use ieee.std_logic_1164.all;
 | 
			
		||||
use ieee.numeric_std.all;
 | 
			
		||||
 | 
			
		||||
library work;
 | 
			
		||||
use work.common.all;
 | 
			
		||||
 | 
			
		||||
entity register_file is
 | 
			
		||||
    generic (
 | 
			
		||||
        SIM        : boolean := false;
 | 
			
		||||
        HAS_FPU    : boolean := true;
 | 
			
		||||
        LOG_LENGTH : natural := 0
 | 
			
		||||
        );
 | 
			
		||||
    port(
 | 
			
		||||
        clk           : in std_logic;
 | 
			
		||||
 | 
			
		||||
        d_in          : in Decode2ToRegisterFileType;
 | 
			
		||||
        d_out         : out RegisterFileToDecode2Type;
 | 
			
		||||
 | 
			
		||||
        w_in          : in WritebackToRegisterFileType;
 | 
			
		||||
 | 
			
		||||
        dbg_gpr_req   : in std_ulogic;
 | 
			
		||||
        dbg_gpr_ack   : out std_ulogic;
 | 
			
		||||
        dbg_gpr_addr  : in gspr_index_t;
 | 
			
		||||
        dbg_gpr_data  : out std_ulogic_vector(63 downto 0);
 | 
			
		||||
 | 
			
		||||
        sim_dump      : in std_ulogic;
 | 
			
		||||
        sim_dump_done : out std_ulogic;
 | 
			
		||||
 | 
			
		||||
        log_out       : out std_ulogic_vector(71 downto 0)
 | 
			
		||||
        );
 | 
			
		||||
end entity register_file;
 | 
			
		||||
 | 
			
		||||
architecture behaviour of register_file is
 | 
			
		||||
    component Microwatt_FP_DFFRFile port (
 | 
			
		||||
        CLK : in std_ulogic;
 | 
			
		||||
 | 
			
		||||
        R1  : in std_ulogic_vector(6 downto 0);
 | 
			
		||||
        R2  : in std_ulogic_vector(6 downto 0);
 | 
			
		||||
        R3  : in std_ulogic_vector(6 downto 0);
 | 
			
		||||
 | 
			
		||||
        D1  : out std_ulogic_vector(63 downto 0);
 | 
			
		||||
        D2  : out std_ulogic_vector(63 downto 0);
 | 
			
		||||
        D3  : out std_ulogic_vector(63 downto 0);
 | 
			
		||||
 | 
			
		||||
        WE  : in std_ulogic;
 | 
			
		||||
        RW  : in std_ulogic_vector(6 downto 0);
 | 
			
		||||
        DW  : in std_ulogic_vector(63 downto 0)
 | 
			
		||||
    );
 | 
			
		||||
    end component;
 | 
			
		||||
 | 
			
		||||
    signal d1: std_ulogic_vector(63 downto 0);
 | 
			
		||||
    signal d2: std_ulogic_vector(63 downto 0);
 | 
			
		||||
    signal d3: std_ulogic_vector(63 downto 0);
 | 
			
		||||
begin
 | 
			
		||||
 | 
			
		||||
    register_file_0 : Microwatt_FP_DFFRFile
 | 
			
		||||
        port map (
 | 
			
		||||
            CLK => clk,
 | 
			
		||||
 | 
			
		||||
            R1  => d_in.read1_reg,
 | 
			
		||||
            R2  => d_in.read2_reg,
 | 
			
		||||
            R3  => d_in.read3_reg,
 | 
			
		||||
 | 
			
		||||
            D1  => d1,
 | 
			
		||||
            D2  => d2,
 | 
			
		||||
            D3  => d3,
 | 
			
		||||
 | 
			
		||||
            WE  => w_in.write_enable,
 | 
			
		||||
            RW  => w_in.write_reg,
 | 
			
		||||
            DW  => w_in.write_data
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
    x_state_check: process(clk)
 | 
			
		||||
    begin
 | 
			
		||||
        if rising_edge(clk) then
 | 
			
		||||
            if w_in.write_enable = '1' then
 | 
			
		||||
                assert not(is_x(w_in.write_data)) and not(is_x(w_in.write_reg)) severity failure;
 | 
			
		||||
            end if;
 | 
			
		||||
        end if;
 | 
			
		||||
    end process x_state_check;
 | 
			
		||||
 | 
			
		||||
    -- Forward any written data
 | 
			
		||||
    register_read_0: process(all)
 | 
			
		||||
    begin
 | 
			
		||||
        d_out.read1_data <= d1;
 | 
			
		||||
        d_out.read2_data <= d2;
 | 
			
		||||
        d_out.read3_data <= d3;
 | 
			
		||||
 | 
			
		||||
        if w_in.write_enable = '1' then
 | 
			
		||||
            if d_in.read1_reg = w_in.write_reg then
 | 
			
		||||
                d_out.read1_data <= w_in.write_data;
 | 
			
		||||
            end if;
 | 
			
		||||
            if d_in.read2_reg = w_in.write_reg then
 | 
			
		||||
                d_out.read2_data <= w_in.write_data;
 | 
			
		||||
            end if;
 | 
			
		||||
            if d_in.read3_reg = w_in.write_reg then
 | 
			
		||||
                d_out.read3_data <= w_in.write_data;
 | 
			
		||||
            end if;
 | 
			
		||||
        end if;
 | 
			
		||||
    end process register_read_0;
 | 
			
		||||
 | 
			
		||||
end architecture behaviour;
 | 
			
		||||
					Loading…
					
					
				
		Reference in New Issue