8-bit Microprocessor Verilog Code Now
// 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:
// ALU controls reg [2:0] alu_op; wire [7:0] alu_result; wire alu_zero; 8-bit microprocessor verilog code
// Instantiate modules alu alu_inst (.a(reg_a), .b(reg_b), .op(alu_op), .result(alu_result), .zero(alu_zero)); // Main control logic always @(posedge clk or
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)); // Instruction fetch pc <
Have you built your own CPU in Verilog? Share your experience or questions in the comments!