2
\$\begingroup\$

I have code for a 64-bit timer register which can take in a 32-bit slice and depending on the inputs, place the slice in the high side or the low side, or increment the counter.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity CSR_TIMER is
    Port ( clk : in STD_LOGIC;
           reset: in STD_LOGIC := '0';
           DATA_IN : in STD_LOGIC_VECTOR (31 downto 0);
           EN_WRITE_LOW : in STD_LOGIC;
           EN_WRITE_HIGH : in STD_LOGIC;
           DATA_LOW_OUT : out STD_LOGIC_VECTOR (31 downto 0);
           DATA_HIGH_OUT : out STD_LOGIC_VECTOR (31 downto 0));
end CSR_TIMER;

architecture Behavioral of CSR_TIMER is
    signal clock,clock_next : unsigned(63 downto 0) := x"0000000000000000";
begin
    clock_next <=
    x"0000000000000000"                     when (reset = '1') else
    clock(63 downto 32) & unsigned(DATA_IN) when (EN_WRITE_LOW = '1') else
    unsigned(DATA_IN) & clock(31 downto 0)  when (EN_WRITE_HIGH = '1') else
    clock+1;
    
    DATA_LOW_OUT <=
    std_logic_vector(clock(31 downto 0));
    
    DATA_HIGH_OUT <=
    std_logic_vector(clock(63 downto 32));

    process(clk)
    begin
        if(rising_edge(clk)) then
            clock<=clock_next;
        end if;
    end process;

end Behavioral;

The trouble that I'm having is that the timer takes up too many physical resources, and I'm looking to shrink it down. This is for a RISC-V Processor where the ISA specifies that a proper processor has 32 of these timers, which is 2KB of on-board memory, and is not friendly to any FPGA. The Data_Low_out and data_high_out are connected to a mux, where they are treated as separate registers at different addresses.

How can I optimize this timer (or a group of 32 timers) to reduce the physical resource usage? This is synthesized using Vivado 2020.1.

\$\endgroup\$
0

1 Answer 1

2
\$\begingroup\$

Optimization

This code is written in the RTL style, which is at a high-level of abstraction. The benefit of RTL is that it is portable to any design synthesis software and target technology. It is also implicitly understood that RTL never implies a specific implementation when the code is synthesized into gates.

Furthermore, there is no standard for RTL to infer a specific implementation. The synthesis tool has the freedom to optimize as it sees fit, and different synthesis tools will yield different result. The results depend more on the way you configure the synthesis tool, and less on the RTL coding style. To try to achieve a specific implementation, you need to study the Vivado documentation to see if the implementation you seek is supported by the tool.

Layout

Here are some general coding style suggestions.

It is strange to see 2 related lines of code with no indentation:

DATA_LOW_OUT <=
std_logic_vector(clock(31 downto 0));

This is more commonly written on a single line:

DATA_LOW_OUT <= std_logic_vector(clock(31 downto 0));

Perhaps you wanted to keep lines short, which is a good goal, but the line is not too long in this case.

Use underscore characters to make large numeric literals easier to read and understand. For example, change:

0000000000000000

to:

0000_0000_0000_0000

Naming

The signal named clock seems more like it is serving as a data type signal than it is a clock type signal. This can be misleading.

Documentation

Add a comment block at the top of the file to describe the design features.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.