add verilog files for project one through five
This commit is contained in:
@@ -1,40 +1,106 @@
|
||||
/**
|
||||
* The Hack CPU (Central Processing unit), consisting of an ALU,
|
||||
* two registers named A and D, and a program counter named PC.
|
||||
* The CPU is designed to fetch and execute instructions written in
|
||||
* The CPU is designed to fetch and execute instructions written in
|
||||
* the Hack machine language. In particular, functions as follows:
|
||||
* Executes the inputted instruction according to the Hack machine
|
||||
* Executes the inputted instruction according to the Hack machine
|
||||
* language specification. The D and A in the language specification
|
||||
* refer to CPU-resident registers, while M refers to the external
|
||||
* memory location addressed by A, i.e. to Memory[A]. The inM input
|
||||
* holds the value of this location. If the current instruction needs
|
||||
* to write a value to M, the value is placed in outM, the address
|
||||
* of the target location is placed in the addressM output, and the
|
||||
* writeM control bit is asserted. (When writeM==0, any value may
|
||||
* appear in outM). The outM and writeM outputs are combinational:
|
||||
* they are affected instantaneously by the execution of the current
|
||||
* instruction. The addressM and pc outputs are clocked: although they
|
||||
* are affected by the execution of the current instruction, they commit
|
||||
* to their new values only in the next time step. If reset==1 then the
|
||||
* CPU jumps to address 0 (i.e. pc is set to 0 in next time step) rather
|
||||
* than to the address resulting from executing the current instruction.
|
||||
* memory location addressed by A, i.e. to Memory[A]. The inM input
|
||||
* holds the value of this location. If the current instruction needs
|
||||
* to write a value to M, the value is placed in outM, the address
|
||||
* of the target location is placed in the addressM output, and the
|
||||
* writeM control bit is asserted. (When writeM==0, any value may
|
||||
* appear in outM). The outM and writeM outputs are combinational:
|
||||
* they are affected instantaneously by the execution of the current
|
||||
* instruction. The addressM and pc outputs are clocked: although they
|
||||
* are affected by the execution of the current instruction, they commit
|
||||
* to their new values only in the next time step. If reset==1 then the
|
||||
* CPU jumps to address 0 (i.e. pc is set to 0 in next time step) rather
|
||||
* than to the address resulting from executing the current instruction.
|
||||
*/
|
||||
|
||||
`default_nettype none
|
||||
module CPU(
|
||||
input clk,
|
||||
input [15:0] inM, // M value input (M = contents of RAM[A])
|
||||
input [15:0] instruction, // Instruction for execution
|
||||
input reset, // Signals whether to re-start the current
|
||||
// program (reset==1) or continue executing
|
||||
// the current program (reset==0).
|
||||
input clk,
|
||||
input [15:0] inM, // M value input (M = contents of RAM[A])
|
||||
input [15:0] instruction, // Instruction for execution
|
||||
input reset, // Signals whether to re-start the current
|
||||
// program (reset==1) or continue executing
|
||||
// the current program (reset==0).
|
||||
|
||||
output [15:0] outM, // M value output
|
||||
output writeM, // Write to M?
|
||||
output [15:0] addressM, // Address in data memory (of M) to read
|
||||
output [15:0] pc // address of next instruction
|
||||
output [15:0] outM, // M value output
|
||||
output writeM, // Write to M?
|
||||
output [15:0] addressM, // Address in data memory (of M) to read
|
||||
output [15:0] pc // address of next instruction
|
||||
);
|
||||
|
||||
// Put your code here:
|
||||
// Put your code here:
|
||||
wire loadA;
|
||||
wire loadD;
|
||||
wire is_A;
|
||||
wire is_C;
|
||||
wire zr;
|
||||
wire ng;
|
||||
wire inc;
|
||||
wire load;
|
||||
wire jump;
|
||||
wire [15:0] toA;
|
||||
wire [15:0] toD;
|
||||
wire [15:0] toPC;
|
||||
wire [15:0] fromA;
|
||||
wire [15:0] fromD;
|
||||
wire [15:0] fromPC;
|
||||
wire [15:0] fromAorM;
|
||||
wire [15:0] fromALU;
|
||||
|
||||
reg [15:0] tempM;
|
||||
reg [15:0] tempPC;
|
||||
|
||||
|
||||
assign is_C = instruction[15] & instruction[14] & instruction[13];
|
||||
assign is_A = ~is_C;
|
||||
|
||||
|
||||
assign loadD = is_C & instruction[4];
|
||||
assign loadA = (is_C & instruction[5]) || is_A;
|
||||
|
||||
assign fromAorM = instruction[12] ? inM : fromA;
|
||||
assign toA = is_A ? instruction : outM;
|
||||
|
||||
|
||||
// jump if j1 bit set and ng bit set
|
||||
// jump if j2 bit set and zr bit set
|
||||
// jump if j3 bit set and zr, ng bit not set
|
||||
assign jump = is_C
|
||||
& ((instruction[2] & ng)
|
||||
|| (instruction[1] & zr)
|
||||
|| (instruction[0] & ~(zr | ng)));
|
||||
assign inc = ~jump;
|
||||
|
||||
assign outM = fromALU;
|
||||
|
||||
//assign toPC = jump? fromA : pc;
|
||||
|
||||
//xxxx xxxx xxxx xxxx
|
||||
Register RegA(clk, toA, loadA, fromA);
|
||||
Register RegD(clk, fromALU, loadD, fromD);
|
||||
PC PC(clk, fromA, jump, inc, reset, pc);
|
||||
ALU ALU(
|
||||
fromD,
|
||||
fromAorM,
|
||||
instruction[11],
|
||||
instruction[10],
|
||||
instruction[9],
|
||||
instruction[8],
|
||||
instruction[7],
|
||||
instruction[6],
|
||||
fromALU,
|
||||
zr,
|
||||
ng
|
||||
);
|
||||
|
||||
assign addressM = fromA;
|
||||
assign writeM = is_C & instruction[3];
|
||||
|
||||
endmodule
|
||||
|
@@ -4,12 +4,24 @@
|
||||
* a reset signal of approx. 20us length
|
||||
*/
|
||||
`default_nettype none
|
||||
module Clock25_Reset20(
|
||||
input CLK, // external clock 100 MHz
|
||||
output clk, // internal clock 25 Mhz
|
||||
output reset // reset signal approx. 20us
|
||||
module Clock25_Reset20(
|
||||
input CLK, // external clock 100 MHz
|
||||
output reg clk, // internal clock 25 Mhz
|
||||
output reg reset // reset signal approx. 20us
|
||||
);
|
||||
|
||||
// Put your code here:
|
||||
// Put your code here:
|
||||
reg boot=1;
|
||||
reg [3:0] ccount=0;
|
||||
reg [12:0] rcount=0;
|
||||
|
||||
always @(posedge CLK) begin
|
||||
if (boot == 1) begin
|
||||
boot <= (rcount == 4095) ? 0 : 1;
|
||||
rcount <= (rcount == 4095) ? 0 : rcount + 1;
|
||||
reset <= (rcount >= 2048) ? 0 : 1;
|
||||
end
|
||||
ccount <= (ccount == 3) ? 0 : ccount + 1;
|
||||
clk <= (ccount >= 2) ? 1 : 0;
|
||||
end
|
||||
endmodule
|
||||
|
@@ -8,12 +8,89 @@
|
||||
*/
|
||||
|
||||
`default_nettype none
|
||||
module HACK(
|
||||
input CLK, // external clock 100 MHz
|
||||
input [1:0] BUT, // user button (0 if pressed, 1 if released)
|
||||
output [1:0] LED // leds (0 off, 1 on)
|
||||
module HACK(
|
||||
input CLK, // external clock 100 MHz
|
||||
input [1:0] BUT, // user button (0 if pressed, 1 if released)
|
||||
output [1:0] LED // leds (0 off, 1 on)
|
||||
);
|
||||
|
||||
// Put your code here:
|
||||
|
||||
wire loadRAM;
|
||||
wire loadIO0;
|
||||
wire loadIO1;
|
||||
wire loadIO2;
|
||||
wire loadIO3;
|
||||
wire loadIO4;
|
||||
wire loadIO5;
|
||||
wire loadIO6;
|
||||
wire loadIO7;
|
||||
wire loadIO8;
|
||||
wire loadIO9;
|
||||
wire loadIOA;
|
||||
wire loadIOB;
|
||||
wire loadIOC;
|
||||
wire loadIOD;
|
||||
wire loadIOE;
|
||||
wire loadIOF;
|
||||
wire [15:0] inRAM;
|
||||
wire [15:0] inIO0;
|
||||
wire [15:0] inIO1;
|
||||
wire [15:0] inIO2=0;
|
||||
wire [15:0] inIO3=0;
|
||||
wire [15:0] inIO4=0;
|
||||
wire [15:0] inIO5=0;
|
||||
wire [15:0] inIO6=0;
|
||||
wire [15:0] inIO7=0;
|
||||
wire [15:0] inIO8=0;
|
||||
wire [15:0] inIO9=0;
|
||||
wire [15:0] inIOA=0;
|
||||
wire [15:0] inIOB;
|
||||
wire [15:0] inIOC;
|
||||
wire [15:0] inIOD;
|
||||
wire [15:0] inIOE;
|
||||
wire [15:0] inIOF;
|
||||
|
||||
wire writeM;
|
||||
wire [15:0] inM;
|
||||
wire [15:0] instruction;
|
||||
wire [15:0] outM;
|
||||
wire [15:0] addressM;
|
||||
wire [15:0] pc;
|
||||
|
||||
wire clk, reset;
|
||||
wire [15:0] outDEBUG0;
|
||||
wire [15:0] outDEBUG1;
|
||||
wire [15:0] outDEBUG2;
|
||||
wire loadDEBUG0;
|
||||
wire loadDEBUG1;
|
||||
wire loadDEBUG2;
|
||||
// Put your code here:
|
||||
assign LED[1:0] = inIO0[1:0];
|
||||
assign outDEBUG0 = inIOB;
|
||||
assign outDEBUG1 = inIOC;
|
||||
assign outDEBUG2 = inIOD;
|
||||
assign loadDEBUG0 = loadIOB;
|
||||
assign loadDEBUG1 = loadIOC;
|
||||
assign loadDEBUG2 = loadIOD;
|
||||
Clock25_Reset20 CLKR(CLK, clk, reset);
|
||||
CPU CPU(clk, inM, instruction, reset, outM, writeM, addressM, pc);
|
||||
|
||||
Memory Memory(addressM, writeM, inM, loadRAM,
|
||||
loadIO0, loadIO1, loadIO2, loadIO3, loadIO4, loadIO5, loadIO6, loadIO7,
|
||||
loadIO8, loadIO9, loadIOA, loadIOB, loadIOC, loadIOD, loadIOE, loadIOF,
|
||||
inRAM, inIO0, inIO1, inIO2, inIO3, inIO4, inIO5, inIO6, inIO7,
|
||||
inIO8, inIO9, inIOA, inIOB, inIOC, inIOD, inIOE, inIOF);
|
||||
|
||||
ROM ROM(pc, instruction);
|
||||
RAM3840 RAM(clk, addressM[11:0], outM, loadRAM, inRAM);
|
||||
|
||||
Register LED12(clk, outM, loadIO0, inIO0);
|
||||
Register BUT12(clk, {14'b0, BUT[1:0]}, 1'b1, inIO1);
|
||||
|
||||
Register DEBUG0(clk, outM, loadIOB, inIOB);
|
||||
Register DEBUG1(clk, outM, loadIOC, inIOC);
|
||||
Register DEBUG2(clk, outM, loadIOD, inIOD);
|
||||
Register DEBUG3(clk, outM, loadIOE, inIOE);
|
||||
Register DEBUG4(clk, outM, loadIOF, inIOF);
|
||||
|
||||
endmodule
|
||||
|
@@ -1,12 +1,12 @@
|
||||
/**
|
||||
* The complete address space of the Hack computer's memory,
|
||||
* including RAM and memory-mapped I/O.
|
||||
* including RAM and memory-mapped I/O.
|
||||
* The chip facilitates read and write operations, as follows:
|
||||
* Read: out(t) = Memory[address(t)](t)
|
||||
* Write: if load(t-1) then Memory[address(t-1)](t) = in(t-1)
|
||||
* In words: the chip always outputs the value stored at the memory
|
||||
* location specified by address. If load==1, the in value is loaded
|
||||
* into the memory location specified by address. This value becomes
|
||||
* In words: the chip always outputs the value stored at the memory
|
||||
* location specified by address. If load==1, the in value is loaded
|
||||
* into the memory location specified by address. This value becomes
|
||||
* available through the out output from the next time step onward.
|
||||
* Address space rules:
|
||||
* RAM 0x0000 - 0x0EFF (3840 words)
|
||||
@@ -16,45 +16,80 @@
|
||||
|
||||
`default_nettype none
|
||||
module Memory(
|
||||
input [15:0] address,
|
||||
input load,
|
||||
output [15:0] out,
|
||||
output loadRAM,
|
||||
output loadIO0,
|
||||
output loadIO1,
|
||||
output loadIO2,
|
||||
output loadIO3,
|
||||
output loadIO4,
|
||||
output loadIO5,
|
||||
output loadIO6,
|
||||
output loadIO7,
|
||||
output loadIO8,
|
||||
output loadIO9,
|
||||
output loadIOA,
|
||||
output loadIOB,
|
||||
output loadIOC,
|
||||
output loadIOD,
|
||||
output loadIOE,
|
||||
output loadIOF,
|
||||
input [15:0] inRAM,
|
||||
input [15:0] inIO0,
|
||||
input [15:0] inIO1,
|
||||
input [15:0] inIO2,
|
||||
input [15:0] inIO3,
|
||||
input [15:0] inIO4,
|
||||
input [15:0] inIO5,
|
||||
input [15:0] inIO6,
|
||||
input [15:0] inIO7,
|
||||
input [15:0] inIO8,
|
||||
input [15:0] inIO9,
|
||||
input [15:0] inIOA,
|
||||
input [15:0] inIOB,
|
||||
input [15:0] inIOC,
|
||||
input [15:0] inIOD,
|
||||
input [15:0] inIOE,
|
||||
input [15:0] inIOF
|
||||
input [15:0] address,
|
||||
input load,
|
||||
output [15:0] out,
|
||||
output loadRAM,
|
||||
output loadIO0,
|
||||
output loadIO1,
|
||||
output loadIO2,
|
||||
output loadIO3,
|
||||
output loadIO4,
|
||||
output loadIO5,
|
||||
output loadIO6,
|
||||
output loadIO7,
|
||||
output loadIO8,
|
||||
output loadIO9,
|
||||
output loadIOA,
|
||||
output loadIOB,
|
||||
output loadIOC,
|
||||
output loadIOD,
|
||||
output loadIOE,
|
||||
output loadIOF,
|
||||
input [15:0] inRAM,
|
||||
input [15:0] inIO0,
|
||||
input [15:0] inIO1,
|
||||
input [15:0] inIO2,
|
||||
input [15:0] inIO3,
|
||||
input [15:0] inIO4,
|
||||
input [15:0] inIO5,
|
||||
input [15:0] inIO6,
|
||||
input [15:0] inIO7,
|
||||
input [15:0] inIO8,
|
||||
input [15:0] inIO9,
|
||||
input [15:0] inIOA,
|
||||
input [15:0] inIOB,
|
||||
input [15:0] inIOC,
|
||||
input [15:0] inIOD,
|
||||
input [15:0] inIOE,
|
||||
input [15:0] inIOF
|
||||
);
|
||||
|
||||
// Put your code here:
|
||||
// Put your code here:
|
||||
wire selA;
|
||||
wire selB;
|
||||
wire loadA;
|
||||
wire loadB;
|
||||
|
||||
wire [15:0] outA;
|
||||
wire [15:0] outB;
|
||||
wire [15:0] outAB;
|
||||
|
||||
DMux DMUX(address[12], address[3], selA, selB);
|
||||
And ANDA(selA,load,loadA);
|
||||
And ANDB(selB,load,loadB);
|
||||
And ANDR(~address[12], load, loadRAM);
|
||||
|
||||
DMux8Way DMUXLOADA(loadA, address[2:0],
|
||||
loadIO0, loadIO1, loadIO2, loadIO3,
|
||||
loadIO4, loadIO5, loadIO6, loadIO7);
|
||||
|
||||
DMux8Way DMUXLOADB(loadB, address[2:0],
|
||||
loadIO8, loadIO9, loadIOA, loadIOB,
|
||||
loadIOC, loadIOD, loadIOE, loadIOF);
|
||||
|
||||
Mux8Way16 Mux8Way16A(
|
||||
inIO0[15:0], inIO1[15:0], inIO2[15:0], inIO3[15:0],
|
||||
inIO4[15:0], inIO5[15:0], inIO6[15:0], inIO7[15:0],
|
||||
address[2:0], outA[15:0]
|
||||
);
|
||||
Mux8Way16 Mux8Way16B(
|
||||
inIO8[15:0], inIO9[15:0], inIOA[15:0], inIOB[15:0],
|
||||
inIOC[15:0], inIOD[15:0], inIOE[15:0], inIOF[15:0],
|
||||
address[2:0], outB[15:0]
|
||||
);
|
||||
|
||||
Mux16 MUX16AB(outA[15:0], outB[15:0], address[3], outAB[15:0]);
|
||||
Mux16 MUX16ABR(inRAM[15:0], outAB[15:0], address[12], out[15:0]);
|
||||
|
||||
endmodule
|
||||
|
Reference in New Issue
Block a user