Created
April 28, 2010 19:35
-
-
Save hlian/382594 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ------------------------------------------------------------------------ | |
// ELE 206: top_module for PUnC Project | |
// Author: Dana Hoffman and Hao Lian (based on Arnab Sinha's code) | |
// Description: A computer! | |
// ------------------------------------------------------------------------ | |
`timescale 1ns / 1ps | |
module top_module(reset, sysclk, uclk, ss, en, led); | |
parameter I_bus_width = 8; | |
parameter D_bus_width = 8; | |
parameter PC_width = 8; | |
parameter RESET=0, FETCH=1, DECODE=2, | |
CMP=3, OUT1=4, OUT2=5, JMP1=6, JMP2=7, | |
SHR=8, SHL=9, ADDM1=10, ADDM2=11, ADDM3=12, | |
NANDM1=13, NANDM2=14, NANDM3=15, | |
STORE1=16, STORE2=17, | |
LDI1=18, LDI2=19, | |
LDM1=20, LDM2=21, LDM3=22, | |
JNZ1=23, JNZ2=24; | |
// System stuff, dclk = delayed(uclk). | |
input sysclk, uclk, reset; | |
wire dclk; | |
// Seven-segment digits. Register SS_display taps into | |
// SS_display_wire. | |
output [6:0] ss; | |
output [3:0] en; | |
output [5:0] led; | |
reg [I_bus_width-1:0] SS_display; | |
// Buses. | |
wire [I_bus_width-1:0] I_bus; | |
wire [D_bus_width-1:0] D_bus; | |
// Control wires: instruction box. | |
wire PC_inc_ctrl, PC_ld_ctrl, | |
I_mem_ld, I_mem_to_I_bus_ctrl; | |
wire [I_bus_width-1:0] PC_value; // Taps the value of PC in IBox | |
// Control wires: execution box. | |
wire A_ld_ctrl, A_shL_ctrl, A_shR_ctrl, | |
D_mem_ld_ctrl, | |
D_mem_to_D_bus_ctrl, A_to_D_bus_ctrl, A_to_I_bus_ctrl, | |
ALU_mode_ctrl, A_neq_0; | |
wire [1:0] A_mode_ctrl; | |
ss_display SD1 (.clock(sysclk), .ssOut(ss), .nIn({PC_value, SS_display}), .enable(en)); | |
delayCounter dc(.sysclk(sysclk), .uclk(uclk), .dclk(dclk)); | |
e_box e(.clk(dclk), .reset(reset), | |
.I_bus(I_bus), .D_bus(D_bus), | |
.A_ld_ctrl(A_ld_ctrl), .A_shL_ctrl(A_shL_ctrl), .A_shR_ctrl(A_shR_ctrl), | |
.D_mem_ld_ctrl(D_mem_ld_ctrl), | |
.D_mem_to_D_bus_ctrl(D_mem_to_D_bus_ctrl), | |
.A_to_D_bus_ctrl(A_to_D_bus_ctrl), | |
.A_to_I_bus_ctrl(A_to_I_bus_ctrl), | |
.ALU_mode_ctrl(ALU_mode_ctrl), .A_mode_ctrl(A_mode_ctrl), .PC_value(PC_value), | |
.A_neq_0(A_neq_0)); | |
i_box i(.clk(dclk), .reset(reset), | |
.PC_inc_ctrl(PC_inc_ctrl), .PC_ld_ctrl(PC_ld_ctrl), | |
.I_mem_to_I_bus_ctrl(I_mem_to_I_bus_ctrl), | |
.I_bus(I_bus), .PC_value(PC_value)); | |
reg [4:0] state; | |
always @(posedge dclk) begin | |
if (reset) state <= FETCH; | |
else begin | |
case (state) | |
FETCH: state <= DECODE; | |
DECODE: begin | |
if (I_bus[7:6] == 2'b10) state <= CMP; | |
else if (I_bus == 8'h10) state <= OUT1; | |
else if (I_bus == 8'h20) state <= JMP1; | |
else if (I_bus == 8'h40) state <= SHR; | |
else if (I_bus == 8'h50) state <= SHL; | |
else if (I_bus == 8'hD0) state <= ADDM1; | |
else if (I_bus == 8'hC0) state <= NANDM1; | |
else if (I_bus == 8'h00) state <= STORE1; | |
else if (I_bus == 8'hE0) state <= LDI1; | |
else if (I_bus == 8'hF0) state <= LDM1; | |
else if (I_bus == 8'h30) state <= JNZ1; | |
end | |
CMP: state <= FETCH; | |
OUT1: state <= OUT2; | |
OUT2: state <= FETCH; | |
JMP1: state <= JMP2; | |
JMP2: state <= FETCH; | |
SHR: state <= FETCH; | |
SHL: state <= FETCH; | |
ADDM1: state <= ADDM2; | |
ADDM2: state <= ADDM3; | |
ADDM3: state <= FETCH; | |
NANDM1: state <= NANDM2; | |
NANDM2: state <= NANDM3; | |
NANDM3: state <= FETCH; | |
STORE1: state <= STORE2; | |
STORE2: state <= FETCH; | |
LDI1: state <= LDI2; | |
LDI2: state <= FETCH; | |
LDM1: state <= LDM2; | |
LDM2: state <= LDM3; | |
LDM3: state <= FETCH; | |
JNZ1: state <= JNZ2; | |
JNZ2: state <= FETCH; | |
endcase | |
end | |
end | |
assign PC_inc_ctrl = (state == DECODE) || | |
(state == CMP) || (state == OUT2) || (state == SHR) || (state == SHL) || | |
(state == ADDM3) || (state == NANDM3) || (state == STORE2) || (state == LDI2) || | |
(state == LDM3); | |
assign I_mem_to_I_bus_ctrl = (state == FETCH) || (state == DECODE) || | |
(state == ADDM1) || (state == ADDM2) || (state == ADDM3) || | |
(state == NANDM1) || (state == NANDM2) || (state == NANDM3) || | |
(state == STORE1) || (state == STORE2) || | |
(state == LDI1) || (state == LDI2) || | |
(state == LDM1) || (state == LDM2) || (state == LDM3) || | |
(state == JNZ1) || (state == JNZ2); | |
assign D_mem_ld_ctrl = (state == STORE1) || (state == STORE2); | |
assign D_mem_to_D_bus_ctrl = | |
(state == ADDM1) || (state == ADDM2) || (state == ADDM3) || | |
(state == NANDM1) || (state == NANDM2) || (state == NANDM3) || | |
(state == LDM1) || (state == LDM2) || (state == LDM3); | |
assign A_ld_ctrl = (state == CMP) | |
|| (state == SHR) || (state == SHL) || (state == ADDM3) | |
|| (state == NANDM3) || (state == LDI2) || (state == LDM3); | |
assign A_mode_ctrl = | |
(state == CMP) ? 2'b11: | |
(state == ADDM3) ? 2'b00: | |
(state == NANDM3) ? 2'b00: | |
(state == LDI2) ? 2'b10: | |
(state == LDM3) ? 2'b01: | |
0; | |
assign ALU_mode_ctrl = | |
(state == ADDM3) ? 0 : | |
(state == NANDM3) ? 1 : 0; | |
assign A_to_I_bus_ctrl = | |
(state == OUT1) || (state == OUT2) || | |
(state == JMP1) || (state == JMP2); | |
assign PC_ld_ctrl = (state == JMP2) || | |
(state == JNZ2 && A_neq_0); | |
assign A_shL_ctrl = (state == SHL); | |
assign A_shR_ctrl = (state == SHR); | |
assign D_mem_to_D_bus_ctrl = | |
(state == ADDM1) || (state == ADDM2) || (state == ADDM3) || | |
(state == NANDM1) || (state == NANDM2) || (state == NANDM3) || | |
(state == LDM1) || (state == LDM2) || (state == LDM3); | |
assign A_to_D_bus_ctrl = (state == STORE1) || (state == STORE2); | |
assign led = state; | |
always @(posedge dclk) begin | |
//SS_display <= I_bus; | |
//SS_display <= D_bus; | |
// We put SS_display here for easier testing and tapping. | |
if (state == OUT2) SS_display <= I_bus; | |
//SS_display <= A_neq_0; | |
end | |
endmodule | |
module e_box(clk, reset, | |
I_bus, D_bus, | |
A_ld_ctrl, A_shL_ctrl, A_shR_ctrl, | |
D_mem_ld_ctrl, D_mem_to_D_bus_ctrl, A_to_D_bus_ctrl, A_to_I_bus_ctrl, | |
ALU_mode_ctrl, A_mode_ctrl, PC_value, | |
A_neq_0); | |
parameter I_bus_width = 8; | |
parameter D_bus_width = 8; | |
// System stuff. | |
input clk, reset; | |
// Buses. | |
inout [I_bus_width-1:0] I_bus; | |
inout [D_bus_width-1:0] D_bus; | |
output A_neq_0; | |
// PC tap. | |
input [I_bus_width-1:0] PC_value; | |
// Control wires. | |
input A_ld_ctrl, A_shL_ctrl, A_shR_ctrl; | |
input D_mem_ld_ctrl; | |
input D_mem_to_D_bus_ctrl, A_to_D_bus_ctrl, A_to_I_bus_ctrl; | |
input ALU_mode_ctrl; | |
input [1:0] A_mode_ctrl; | |
// Local storage: data memory and accumulator. | |
reg [D_bus_width-1:0] D_mem[1:0]; | |
reg signed [D_bus_width-1:0] A; | |
always @(posedge clk) begin | |
if (reset) begin | |
D_mem[I_bus] <= 0; | |
A <= 0; | |
end | |
else begin | |
D_mem[I_bus] <= D_mem_ld_ctrl ? D_bus : D_mem[I_bus]; | |
A <= | |
A_shL_ctrl ? A << 1 : | |
A_shR_ctrl ? A >>> 1 : | |
A_ld_ctrl && (A_mode_ctrl == 2'b00) ? | |
(ALU_mode_ctrl == 0 ? A + D_bus : ~(A & D_bus)) : | |
A_ld_ctrl && (A_mode_ctrl == 2'b10) ? I_bus : | |
A_ld_ctrl && (A_mode_ctrl == 2'b01) ? D_bus : | |
A_ld_ctrl && (A_mode_ctrl == 2'b11) ? (A[7] == 1) : A; | |
end | |
end | |
// Tri-state buffers. | |
assign D_bus = D_mem_to_D_bus_ctrl ? D_mem[I_bus] : | |
A_to_D_bus_ctrl ? A : 8'bz; | |
assign I_bus = A_to_I_bus_ctrl ? A : 8'bz; | |
assign A_neq_0 = (A != 0); | |
endmodule | |
module i_box(clk, reset, PC_inc_ctrl, PC_ld_ctrl, | |
I_mem_to_I_bus_ctrl, I_bus, PC_value); | |
parameter I_bus_width = 8; | |
parameter PC_width = 8; | |
// System stuff. | |
input clk, reset; | |
// Control wires. | |
input PC_inc_ctrl, PC_ld_ctrl, | |
I_mem_to_I_bus_ctrl; | |
inout [I_bus_width-1:0] I_bus; | |
output [PC_width-1:0] PC_value; | |
// Local storage: instruction memory and program counter. | |
reg [I_bus_width-1:0] I_mem[255:0]; | |
reg [PC_width-1:0] PC; | |
integer i; | |
always @(posedge clk) begin | |
if (reset) begin | |
PC <= 0; | |
i = 0; I_mem[i] <= 8'he0; // ldi 32 | |
i = i + 1; I_mem[i] <= 8'h20; | |
i = i + 1; I_mem[i] <= 8'h00; // store (00) | |
i = i + 1; I_mem[i] <= 8'h00; | |
i = i + 1; I_mem[i] <= 8'he0; // ldi 18 | |
i = i + 1; I_mem[i] <= 8'h12; | |
i = i + 1; I_mem[i] <= 8'h00; // store (01) | |
i = i + 1; I_mem[i] <= 8'h01; | |
i = i + 1; I_mem[i] <= 8'h10; // out | |
i = i + 1; I_mem[i] <= 8'h00; | |
i = i + 1; I_mem[i] <= 8'hf0; // ldm (00) | |
i = i + 1; I_mem[i] <= 8'h00; | |
i = i + 1; I_mem[i] <= 8'h10; // out | |
i = i + 1; I_mem[i] <= 8'h00; | |
i = i + 1; I_mem[i] <= 8'he0; // ldi CMP_C_D | |
i = i + 1; I_mem[i] <= 8'h58; | |
i = i + 1; I_mem[i] <= 8'h20; // jmp | |
i = i + 1; I_mem[i] <= 8'h00; | |
i = 8'h12; I_mem[i] <= 8'hf0; // ldm (01) | |
i = i + 1; I_mem[i] <= 8'h01; | |
i = i + 1; I_mem[i] <= 8'hc0; // nandm (01) | |
i = i + 1; I_mem[i] <= 8'h01; | |
i = i + 1; I_mem[i] <= 8'h00; // store (08) | |
i = i + 1; I_mem[i] <= 8'h08; | |
i = i + 1; I_mem[i] <= 8'he0; // ldi 01 | |
i = i + 1; I_mem[i] <= 8'h01; | |
i = i + 1; I_mem[i] <= 8'hd0; // addm (08) | |
i = i + 1; I_mem[i] <= 8'h08; | |
i = i + 1; I_mem[i] <= 8'hd0; // addm (00) | |
i = i + 1; I_mem[i] <= 8'h00; | |
i = i + 1; I_mem[i] <= 8'h00; // store (00) | |
i = i + 1; I_mem[i] <= 8'h00; | |
i = i + 1; I_mem[i] <= 8'h10; // out | |
i = i + 1; I_mem[i] <= 8'h00; | |
i = i + 1; I_mem[i] <= 8'hf0; // ldm (01) | |
i = i + 1; I_mem[i] <= 8'h01; | |
i = i + 1; I_mem[i] <= 8'h10; // out | |
i = i + 1; I_mem[i] <= 8'h00; | |
i = i + 1; I_mem[i] <= 8'he0; // ldi cmp_c_d | |
i = i + 1; I_mem[i] <= 8'h58; | |
i = i + 1; I_mem[i] <= 8'h20; // jmp | |
i = i + 1; I_mem[i] <= 8'h00; | |
i = 8'h30; I_mem[i] <= 8'hf0; // ldm (00) | |
i = i + 1; I_mem[i] <= 8'h00; | |
i = i + 1; I_mem[i] <= 8'hc0; // nandm (00) | |
i = i + 1; I_mem[i] <= 8'h00; | |
i = i + 1; I_mem[i] <= 8'h00; // store (08) | |
i = i + 1; I_mem[i] <= 8'h08; | |
i = i + 1; I_mem[i] <= 8'he0; // ldi 01 | |
i = i + 1; I_mem[i] <= 8'h01; | |
i = i + 1; I_mem[i] <= 8'hd0; // addm (08) | |
i = i + 1; I_mem[i] <= 8'h08; | |
i = i + 1; I_mem[i] <= 8'hd0; // addm (01) | |
i = i + 1; I_mem[i] <= 8'h01; | |
i = i + 1; I_mem[i] <= 8'h00; // store (01) | |
i = i + 1; I_mem[i] <= 8'h01; | |
i = i + 1; I_mem[i] <= 8'h10; // out | |
i = i + 1; I_mem[i] <= 8'h00; | |
i = i + 1; I_mem[i] <= 8'hf0; // ldm (00) | |
i = i + 1; I_mem[i] <= 8'h00; | |
i = i + 1; I_mem[i] <= 8'h10; // out | |
i = i + 1; I_mem[i] <= 8'h00; | |
i = i + 1; I_mem[i] <= 8'he0; // ldi cmp_c_d | |
i = i + 1; I_mem[i] <= 8'h58; | |
i = i + 1; I_mem[i] <= 8'h20; // jmp | |
i = i + 1; I_mem[i] <= 8'h00; | |
i = 8'h50; I_mem[i] <= 8'h80; // cmp | |
i = i + 1; I_mem[i] <= 8'h00; | |
i = i + 1; I_mem[i] <= 8'h30; // jnz D_minus_C | |
i = i + 1; I_mem[i] <= 8'h30; | |
i = i + 1; I_mem[i] <= 8'he0; // ldi C_minus_D | |
i = i + 1; I_mem[i] <= 8'h12; | |
i = i + 1; I_mem[i] <= 8'h20; // jmp | |
i = i + 1; I_mem[i] <= 8'h00; | |
i = 8'h58; I_mem[i] <= 8'hf0; // ldm (01) | |
i = i + 1; I_mem[i] <= 8'h01; | |
i = i + 1; I_mem[i] <= 8'hC0; // nandm (01) | |
i = i + 1; I_mem[i] <= 8'h01; | |
i = i + 1; I_mem[i] <= 8'h00; // store (08) | |
i = i + 1; I_mem[i] <= 8'h08; | |
i = i + 1; I_mem[i] <= 8'he0; // ldi (01) | |
i = i + 1; I_mem[i] <= 8'h01; | |
i = i + 1; I_mem[i] <= 8'hd0; // addm (08) | |
i = i + 1; I_mem[i] <= 8'h08; | |
i = i + 1; I_mem[i] <= 8'hd0; // addm (00) | |
i = i + 1; I_mem[i] <= 8'h00; | |
i = i + 1; I_mem[i] <= 8'h30; // jnz GCD_NOT_DONE | |
i = i + 1; I_mem[i] <= 8'h50; | |
i = i + 1; I_mem[i] <= 8'hf0; // ldm (00) | |
i = i + 1; I_mem[i] <= 8'h00; | |
i = i + 1; I_mem[i] <= 8'h10; // out | |
i = i + 1; I_mem[i] <= 8'h00; | |
end | |
else begin | |
PC <= PC_inc_ctrl ? PC + 1 : | |
PC_ld_ctrl ? I_bus : | |
PC; | |
end | |
end | |
// Tap PC. | |
assign PC_value = PC; | |
// Tri-state buffer. | |
assign I_bus = I_mem_to_I_bus_ctrl ? I_mem[PC] : 8'bz; | |
endmodule |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment