How to make a synthesizable Instruction Memory in SystemVerilog?
First of all, does it really matter what the internal implementation looks like? As long as the behavior of the module at its ports is correct, what difference does it make?
As you put more code into the rom, the synthesis tools will probably decide at some point to turn it into an actual memory (e.g., BRAM on an FPGA).
But in practice, you'll quickly get tired of editing your software in the RTL source code. Instead, you'll want to create (or get) an assembler or compiler, and use an external file to initialize the contents of the rom from the output of that. Different tools will have their own ways to accomplish this.1 This will also eliminate the need to re-synthesize the hardware each time you want to tweak the software.

1 You mentioned &quot;Vivado&quot; in a comment, so I'll assume you're targeting Xilinx FPGAs. I once created a custom CPU for a Xilinx project, and I was able to adapt a &quot;universal assembler&quot; written in Ruby to generate .coe (&quot;coefficient&quot;) files for the instruction memory so that it could be synthesized. I also wrote a separate script that converted the .coe file into Verilog source code for simulation in Modelsim.