Logo DWBI.org Login / Sign Up
Sign Up
Have Login?
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.
Login
New Account?
Recovery
Go to Login
By continuing you indicate that you agree to Terms of Service and Privacy Policy of the site.

Code | 8-bit Microprocessor Verilog

// ALU controls reg [2:0] alu_op; wire [7:0] alu_result; wire alu_zero;

always @(posedge clk or posedge rst) begin if (rst) begin registers[0] <= 8'h00; registers[1] <= 8'h00; registers[2] <= 8'h00; registers[3] <= 8'h00; end else if (wr_en) begin registers[reg_sel_wr] <= wr_data; end end endmodule module processor ( input clk, rst, output [15:0] addr_bus, inout [7:0] data_bus, output mem_read, mem_write ); // Internal signals reg [15:0] pc; reg [7:0] ir; reg [7:0] alu_out; reg zero_flag; // Register selects and controls reg [1:0] reg_sel_a, reg_sel_b, reg_sel_wr; reg [7:0] wr_data; reg wr_en; wire [7:0] reg_a, reg_b;

// Instantiate modules alu alu_inst (.a(reg_a), .b(reg_b), .op(alu_op), .result(alu_result), .zero(alu_zero)); 8-bit microprocessor verilog code

Have you built your own CPU in Verilog? Share your experience or questions in the comments!

reg_file reg_inst (.clk(clk), .rst(rst), .reg_sel_a(reg_sel_a), .reg_sel_b(reg_sel_b), .reg_sel_wr(reg_sel_wr), .wr_data(wr_data), .wr_en(wr_en), .reg_a_out(reg_a), .reg_b_out(reg_b)); // ALU controls reg [2:0] alu_op; wire [7:0]

always #5 clk = ~clk;

// Control FSM states reg [2:0] state; localparam FETCH = 3'b000, DECODE = 3'b001, EXECUTE = 3'b010, MEM_READ = 3'b011, MEM_WRITE = 3'b100; pc : ((state == MEM_READ || state == MEM_WRITE)

// Main control logic always @(posedge clk or posedge rst) begin if (rst) begin pc <= 16'h0000; ir <= 8'h00; state <= FETCH; wr_en <= 1'b0; end else begin case (state) FETCH: begin ir <= data_bus; // Instruction fetch pc <= pc + 1; state <= DECODE; end DECODE: begin wr_en <= 1'b0; case (ir[7:4]) // Opcode in upper nibble 4'b0001: begin // MOV A, B reg_sel_wr <= 2'b00; wr_data <= reg_b; wr_en <= 1'b1; state <= FETCH; end 4'b0010: begin // ADD A, B reg_sel_a <= 2'b00; reg_sel_b <= 2'b01; alu_op <= 3'b000; state <= EXECUTE; end 4'b0011: begin // SUB A, B reg_sel_a <= 2'b00; reg_sel_b <= 2'b01; alu_op <= 3'b001; state <= EXECUTE; end 4'b0100: begin // JMP pc <= ir[3:0], data_bus; state <= FETCH; end 4'b0101: begin // JZ if (zero_flag) pc <= ir[3:0], data_bus; else state <= FETCH; end 4'b0110: begin // LD A, [addr] state <= MEM_READ; end 4'b0111: begin // ST [addr], A state <= MEM_WRITE; end 4'b1000: state <= FETCH; // HLT default: state <= FETCH; endcase end EXECUTE: begin reg_sel_wr <= 2'b00; // Write back to A wr_data <= alu_result; wr_en <= 1'b1; zero_flag <= alu_zero; state <= FETCH; end MEM_READ: begin reg_sel_wr <= 2'b00; wr_data <= data_bus; wr_en <= 1'b1; state <= FETCH; end MEM_WRITE: begin state <= FETCH; end endcase end end endmodule Here's a simple testbench to run a few instructions:

// Memory interface assign addr_bus = (state == FETCH) ? pc : ((state == MEM_READ || state == MEM_WRITE) ? ir[7:0], reg_b : 16'hzzzz); assign data_bus = (state == MEM_WRITE) ? reg_a : 8'hzz; assign mem_read = (state == FETCH || state == MEM_READ); assign mem_write = (state == MEM_WRITE);

module processor_tb; reg clk, rst; wire [15:0] addr; wire [7:0] data; wire mem_read, mem_write; processor uut (.clk(clk), .rst(rst), .addr_bus(addr), .data_bus(data), .mem_read(mem_read), .mem_write(mem_write));