Not to disturb the flow here, but attached is a draft I made based on
your previous skeleton.
One thing I noticed when writing this is the constraint posed by the
convention of registering output. For instance, the output of the
memory stage should be a mux between a direct forward of the ALU stage
and the fetched word. However, the output from the memory module is
already registered, so if I understand this right, we can't do the mux
within the module itself. My solution was to rip out such cases from
stage 2 and 4 and do the combinatorics in the top-level module.
Comparing to your new fetch stage, I see a have not made the PC
available as a return address. An alternative to yours would be to make
it readable as a register so that it would be copied before the jump;
you probably though of that, and I guess it depends whether we need more
than one level of calls.
// Instruction Format
//
`define QMODE_BITS 31:30
`define QOP_BITS 29:26
`define QIMM_BIT 25
`define IZ_BITS 25:21
`define IX_BITS 20:16
`define IY_BITS 15:11
`define IMM_BITS 15:0
`define IMM_SIGN_BIT 15
// Instruction Format: Major Operating Mode
//
`define QMODE_ARITH 0
`define QMODE_FETCH 1
`define QMODE_STORE 2
`define QMODE_BRANCH 3
// Instruction Format: Branch Condition
//
// These overlaps with QOP_BITS which is OK since ALU is not used when
// branching.
//
`define BNOT_BIT 29 // negates branch condition
`define BZERO_BIT 28 // branch if zero (can combine with BNEG_BIT)
`define BNEG_BIT 27 // branch if negative
//
// The branch conditions can be expanded to:
//
// 3'b000 noop 3'b100 branch always (jump)
// 3'b001 branch if negative 3'b101 branch if non-negative
// 3'b010 branch if zero 3'b110 branch if non-zero
// 3'b011 branch if non-positive 3'b111 branch if positive
// The Top-Level CPU Module
//
module ogmisc(clock, reset, do_upload, upload_addr, upload_data);
input clock;
input reset;
input do_upload;
input[8:0] upload_addr;
input[31:0] upload_data;
wire[31:0] s1_insn, s2_insn, s3_insn;
wire[31:0] s2_x;
wire[31:0] s2_y_if_reg, s2_y_if_imm, s2_y, s3_y;
wire[4:0] s4_iz;
wire[31:0] s3_z, s4_z, s4_z_if_fetch, s4_z_if_not_fetch;
wire s4_is_fetch;
ogmisc_stg1_fetch stg1(
clock, reset,
do_upload, upload_addr, upload_data,
s1_insn,
s2_insn[`BNOT_BIT], s2_insn[`BZERO_BIT], s2_insn[`BNEG_BIT], s2_x, s2_y);
ogmisc_stg2_regio stg2(
clock, reset, clock_2x, phase,
s1_insn,
s2_insn, s2_x, s2_y_if_reg,
s4_iz, s4_z);
assign s2_y_if_imm = {{16{s2_insn[`IMM_SIGN_BIT]}}, s2_insn[`IMM_BITS]};
assign s2_y = s2_insn[`QIMM_BIT]? s2_y_if_imm : s2_y_if_reg;
ogmisc_stg3_alu stg3(
clock, reset,
s2_insn, s2_x, s2_y,
s3_insn, s3_z, s3_y);
ogmisc_stg4_memio stg4(
clock, reset,
s3_insn, s3_z, s3_y,
s4_iz, s4_is_fetch, s4_z_if_fetch, s4_z_if_not_fetch);
assign s4_z = s4_is_fetch? s4_z_if_fetch : s4_z_if_not_fetch;
endmodule
// Stage 1: Instruction Fetch
//
module ogmisc_stg1_fetch(clock, reset, do_upload, upload_addr, upload_data,
insn_out,
s2_bnot, s2_bzero, s2_bneg, s2_x, s2_y);
input clock;
input reset;
input do_upload;
input[8:0] upload_addr;
input[31:0] upload_data;
output[31:0] insn_out;
input s2_bnot;
input s2_bzero;
input s2_bneg;
input[31:0] s2_x;
input[31:0] s2_y;
reg is_branch_insn;
wire is_zero = s2_x == 0;
wire is_neg = s2_x[31];
wire do_branch = is_branch_insn
&& s2_bnot != (is_zero == s2_bzero && is_neg == s2_bneg);
reg [8:0] pc;
wire [8:0] next_pc = do_branch ? s2_y : pc;
always @(posedge clock) begin
pc <= next_pc + 1;
is_branch_insn <= insn_out[`QMODE_BITS] == `QMODE_BRANCH;
end
RAMB16_S36_S36 program_memory (
.CLKA(clock), .SSRA(1'b0),
.ADDRA(next_pc),
.ENA(1'b1), .DOA(insn_out), .DOPA(),
.WEA(1'b0), .DIA(32'b0), .DIPA(4'b0),
.CLKB(clock), .SSRB(1'b0),
.ADDRB(upload_addr),
.ENB(1'b1), .DOB(), .DOPB(),
.WEB(do_upload), .DIB(upload_data), .DIPB(4'b0));
endmodule
// Stages 2, 5: Register Fetch and Write-Back
//
module ogmisc_stg2_regio(clock, reset, clock_2x, phase,
insn,
insn_out, x_out, y_out_if_reg,
iz, z);
input clock;
input reset;
input clock_2x;
input phase;
input[31:0] insn;
output[31:0] insn_out;
output[31:0] x_out;
output[31:0] y_out_if_reg;
input[4:0] iz;
input[31:0] z;
reg[31:0] regfile[0:31];
reg[31:0] x_out, y_out_if_reg;
wire[4:0] ix = insn[IX_BITS];
wire[4:0] iy = insn[IY_BITS];
always @(posedge clock_2x) begin
if (phase == 1) // falling edge of clock (right?)
regfile[iz] <= z; // iz = 0 for no-write
else begin
x_out <= regfile[ix];
y_out_if_reg <= regfile[iy];
end
end
endmodule
// Stage 3: ALU
//
module ogmisc_stg3_alu(clock, reset, insn, x, y, insn_out, z_out, y_out);
input clock;
input reset;
input[31:0] insn;
input[31:0] x;
input[31:0] y;
output[31:0] insn_out;
output[31:0] z_out;
output[31:0] y_out;
parameter QOP_AND = 0;
parameter QOP_NAND = 1;
parameter QOP_OR = 2;
parameter QOP_XOR = 3;
parameter QOP_SL = 4;
parameter QOP_ADD = 5;
parameter QOP_SUB = 6;
parameter QOP_MULT = 7;
reg[31:0] z_out;
always @(posedge clock) begin
case (insn[`QOP_BITS])
QOP_AND: z_out <= x & y;
QOP_NAND: z_out <= ~(x & y);
QOP_OR: z_out <= x | y;
QOP_XOR: z_out <= x ^ y;
QOP_SL: z_out <= x << y;
QOP_ADD: z_out <= x + y; // FIXME. Explicit instatiate ADDSUB
QOP_SUB: z_out <= x - y; // ...
QOP_MULT: z_out <= x * y; // FIXME. Explicit instatiate.
endcase
end
endmodule
// Stage 4: The Memory Access Stage
//
module ogmisc_stg4_memio(clock, reset, insn, z, y, iz_out,
is_fetch, z_out_if_fetch, z_out_if_not_fetch);
input clock;
input reset;
input[31:0] insn;
input[31:0] z;
input[31:0] y;
output[4:0] iz_out;
output is_fetch;
output[31:0] z_out_if_fetch;
output[31:0] z_out_if_not_fetch;
wire is_store = insn[`QMODE_BITS] == `QMODE_STORE;
reg is_fetch;
reg[31:0] z_out_if_not_fetch;
always @(posedge clock) begin
is_fetch <= insn[`QMODE_BITS] == `QMODE_FETCH;
z_out_if_not_fetch <= z;
end
RAMB16_S36_S36 local_memory(
.CLKA(clock), .SSRA(1'b0),
.ADDRA(z[8:0]),
.ENA(1'b1), .DOA(z_out_if_fetch), .DOPA(),
.WEA(is_store), .DIA(y), .DIPA(4'b0),
.CLKB(1'b0), .SSRB(1'b0),
.ADDRB(9'b0),
.ENB(1'b0), .DOB(), .DOPB(),
.WEB(1'b0), .DIB(32'b0), .DIPB(4'b0));
endmodule
_______________________________________________
Open-graphics mailing list
[email protected]
http://lists.duskglow.com/mailman/listinfo/open-graphics
List service provided by Duskglow Consulting, LLC (www.duskglow.com)