-1

I need to create a Verilog module which accepts the clock, a reset, the immediate value from the instruction word (least significant byte), and the zero output from the ALU as inputs and generates an 8-bit Program Counter (PC) for the output. The assignment says to note that in this architecture when we have a branch, the next PC value should be the current PC value plus the offset which is extracted from the branch instruction. The offset is represented in two’s complement, so the range of branch target is from PC - 128 to PC + 127. Note that the value of PC should not exceed 0xFF as we have a 256-deep instruction memory. You do not need to check for this condition in your hardware.

Here's what I have so far but I know this is incomplete and I'm not sure what to do with the immediate or if I need to add something for the branch instruction. Any help/suggestions?

module pc(input clk,
    input rst,
    input [7:0] immediate,
    input alu_output,
    output [7:0] pc)

reg [7:0] pc;

always@(posedge clk)
    begin
        if(rst)
            begin
                pc <= 0;
            end
        else
            begin
                pc <= pc + 1;
            end             
    end
endmodule
dms94
  • 32
  • 1
  • 1
  • 6

3 Answers3

0

I am not generally in the business of doing other peoples homework so I'll just try to help you along. (Just like that annoying teacher who'll never answer your questions directly.)

Although your text did not specify, I also assume that you should be able to perform absolute branches (also known as jumps).

For branching you need to use an adder. You already have an adder used for you PC = PC + 1 operation, it would be really nice to re-use this adder for branching. This adder must be placed somewhere in front of your PC-register. What to add must be decided by your circuit.

Your program counter must be able to: load immediate from instruction word or add branch value or add 1. One of these three operations will be performed given certain conditions. In digital circuits multiplexers are a great way of making decisions based on conditions. I suggest you figure out what your conditions are and draw yourself a nice figure of how this needs to work. Then you try to program it afterwards.

Hida
  • 767
  • 5
  • 20
  • Just for correctness, what he wants is a relative jump, not an absolute jump as his immediate value is added to the current PC to make a jump, not loaded into the PC. – Unn Apr 04 '16 at 22:18
  • Was it unclear that I wrote about both? I just went ahead and assumed that his assignment needed both although he had not specified it. – Hida Apr 05 '16 at 07:51
0

You have done most of the job yourself. Why don't you add one more control input, call it branch. When branch is 0, you write pc <= pc +1 as you already have. When branch is 1, you write:

begin
    next_pc = pc +{ {{24{immediate[8] }}, immediate[8:0] };
    if (next_pc > 255)
        next_pc = 255;

    pc  <= next_pc;
end

where {{24{immediate[8] }} sign extends the sign bit of immediate, i.e. repeats immediate[8], 24 times.

Ari
  • 7,251
  • 11
  • 40
  • 70
0

There must be an input related to indicate, whether it is a branch instruction or not.

Typically, from processor point of view, a subset of the instruction is used to indicate, whether PC should be normally incremented or there is branch/jump instruction.

In your case, we can take an extra input to indicate, branch instruction.

always @ (posedge clk)
begin
  if (rst)
    pc <= 'h0;
  else if (branch_inst) // Extra input port "branch_inst"
    pc <= pc + immediate; // immediate in 2's complement, signed form
  else 
    pc <= pc + 1'b1;
end
Karan Shah
  • 1,912
  • 1
  • 29
  • 42