Addressing a memory

We need to put our instructions in memory.

Design a memory where the program can be stored. A memory implementation in Verilog is shown in Figure 11.

module memory(clk, write_enable, address, data_in, data_out);

   parameter address_width = 32;
   parameter data_width = 32;
   parameter size = 256;

   input clk;
   input write_enable;
   input [address_width-1:0] address;
   input [data_width-1:0] data_in;
   output[data_width-1:0] data_out;

   wire clk;
   wire write_enable;
   wire [address_width-1:0] address;
   wire [data_width-1:0] data_in;

   reg [data_width-1:0] memory [0:size-1];

   initial begin
     $readmemh("memory_contents.txt", memory);
   end

   always @(posedge clk) begin
     if (write_enable == 1) 
       memory[address] <= data_in;
   end 

   assign data_out = memory[address];

endmodule    

Figure 11. A memory in Verilog.

This the Verilog view - other views are VHDL - SystemC-TLM

Create a pc that reads addresses expressed in bytes. Meaning that it increments itself with four for each instruction read. A program counter implementation in Verilog is shown in Figure 12.

module pc(clk, pc_out);

   parameter pc_width = 32;

   input clk;
   output[pc_width-1:0] pc_out;

   wire clk;
   
   reg [pc_width-1:0] pc_value = 'b0;

   always @(posedge clk)
     pc_value <= pc_value + 4;
    
   assign pc_out = pc_value;

endmodule    

Figure 12. A program counter in Verilog.

This the Verilog view - other views are VHDL - SystemC-TLM

Connect the pc and the memory into a design, so that when it runs, the program is read, and printed.