SAP Simple As Possible Computer Malvino - Verilog Code
SAP Simple As Possible Computer Malvino - Verilog Code
13th January 2014 SAP simple as possible computer Malvino: Verilog
code
FSM finite state machine based verilog coding of
SAP
the architecture of SAP simple as possible is the most basic and effective architecture to understand the
computer architecture. The very famous book explaining this SAP is Digital Computer Electronics by
Malvino . Brown.
Although a very detail explanation of SAP is in this book . Some TTL IC's are also mentioned to
implement SAP on Breadboard. It is indeed a very effective book to understand what behind curtain is
happening when a computer works. This understanding is very important for the Technocrates(Engineers
) related to computer area.
The block diagram of SAP1 is shown below.
[http://2.bp.blogspot.com/
QxaKR55sDD8/UtRJ7pgKuBI/AAAAAAAAAF4/JKodBkHzB4/s1600/FIG.2.0.jpg]
Verilog code for this SAP implementation is shown below.
//programm counter code written by some indian guy for SAP simple as possible computer
module pc( Cp, nCLK, nCLR, Ep, WBUSlower);
input Cp;
input nCLK;
input nCLR;
input Ep;
output[3:0] WBUSlower;
http://technoembed.blogspot.com.br/2014/01/sapsimpleaspossiblecomputermalvino.html 1/7
22/02/2015 SAP simple as possible computer Malvino: Verilog code
//reg[3:0] nextPC;
reg[3:0] WBUSlower;
always @(negedge nCLK) // negative edge of nCLK means positive edge of CLK
begin
if( Cp == 1)
/* Increment PC on every negative edge of nCLK
* (ie: positive edge of CLK mid point of single T state
*/
begin
WBUSlower = WBUSlower + 1;
end
if ( nCLR == 0)
/* Reset Program Counter */
begin
//nextPC = 4'b0000;
WBUSlower = 4'b0000;
end
end
/*
* Keep WBUS in high impedence state when Ep is low (during this time some other module is using
* When Ep is high, output the contents of PC to WBUS
*/
//assign WBUSlower = (Ep) ? nextPC : 4'bzzzz;
endmodule
module inputMAR(nLm, clk, in, ram_addr, ram_nrd, ram_nwr, run_prog);
input clk, nLm, run_prog; //run_prog = 1 means in run mode not in programming mode
output ram_nrd, ram_nwr;
reg ram_nrd, ram_nwr;
parameter wordsize = 4;
input [wordsize1:0] in;
output [wordsize1:0] ram_addr;
reg [wordsize1:0] ram_addr;
always @ (posedge clk)
begin
if(run_prog) begin
{ram_nrd, ram_nwr} = 2'b01; //make nrd enabled and nwr disabled b/c in run mode ram become ROM
if(!nLm) ram_addr = in;
else ram_addr <= ram_addr;
end
else begin
{ram_nrd, ram_nwr} = 2'b10;
if(!nLm) ram_addr = in; //make nrd enabled and nwr disabled b/c in run mode
else ram_addr <= ram_addr;
end
end
endmodule
module ram(clk, nrd, nwr, nce, addr, data);
input clk, nrd, nwr, nce;
http://technoembed.blogspot.com.br/2014/01/sapsimpleaspossiblecomputermalvino.html 2/7
22/02/2015 SAP simple as possible computer Malvino: Verilog code
parameter wrdsize = 8;
parameter logwrd = 3;//wrdsize'bz;
parameter addrsize = 4;
inout [wrdsize1:0] data;
reg [wrdsize1:0] dataout;
input [logwrd1:0] addr;
reg [wrdsize1:0] rammem[0:2**addrsize];
always @ (nce or nwr or nrd) //asynchronous RAM
begin
if(!nrd)
dataout <= !nce?rammem[addr]:8'bz;
else if(!nwr)
rammem[addr] <= !nce?data:rammem[addr];
end
assign data =dataout;
endmodule
module IR(clk, nli, nei, clr, wbus, wbuslower, wbusup);
input clk, nli, nei, clr;
input [7:0] wbus;
output [3:0] wbuslower, wbusup;
reg [7:0]wbuss ;
wire[7:0] wbusloww;
reg [3:0] wbuslower;
assign wbusup = wbuss[7:4];
assign wbusloww = wbuss[3:0];
always @ (posedge clk)
begin
if (clr)begin wbuss = 8'b0; wbuslower = 4'bz; end
else if(!nli) begin
wbuss = wbus; wbuslower = 4'bz; end
if (!nei) begin
wbuslower = wbusloww;
end
end
endmodule
module accumulator(clk, nLa, Ea, accout, accin, accreg);
input clk, nLa, Ea;
parameter wordsize = 8;
input [wordsize1:0] accin;
output [wordsize1:0] accout, accreg;
reg [wordsize1:0] accout, accreg;
always @(posedge clk)
begin
if(!nLa)
begin
accreg <= accin; accout <= 8'bz;
end
if(Ea)
begin
http://technoembed.blogspot.com.br/2014/01/sapsimpleaspossiblecomputermalvino.html 3/7
22/02/2015 SAP simple as possible computer Malvino: Verilog code
accout <= accreg;
end
end
endmodule
module addsub(Su, Eu, ina, inb, result);
input Su, Eu;
parameter wordsize = 8;
input [wordsize1:0] ina, inb;
output [wordsize1:0] result;
assign result = Eu?(Su?inainb:ina+inb):8'bz;
endmodule
module regB(nLb, clk, in, out);
input clk, nLb;
parameter wordsize = 8;
input [wordsize1:0] in;
output [wordsize1:0] out;
reg [wordsize1:0] out;
always @ (posedge clk)
begin
if(!nLb) out = in;
end
endmodule
module outreg(nLo, clk, in, out);
input clk, nLo;
parameter wordsize = 8;
input [wordsize1:0] in;
output [wordsize1:0] out;
reg [wordsize1:0] out;
always @ (posedge clk)
begin
if(!nLo) out = in;
end
endmodule
module control_unit(clk, clr, cntrl_bus, opcode);
input clk,clr;
parameter opcodesize = 4;
input [opcodesize1:0] opcode;
parameter cntrlbussize = 12;
parameter T1 = 6'b000001,
T2 = 6'b000010,
T3 = 6'b000100,
T4 = 6'b001000,
T5 = 6'b010000,
T6 = 6'b100000;
output [cntrlbussize1:0] cntrl_bus;
// ring counter
reg [5:0] ringcount;
http://technoembed.blogspot.com.br/2014/01/sapsimpleaspossiblecomputermalvino.html 4/7
22/02/2015 SAP simple as possible computer Malvino: Verilog code
reg [cntrlbussize1:0] cntrl_bus;
wire [5:0]state ;
always @ (negedge clk)
begin
if (clr)
ringcount = 6'b000001;
else case(ringcount)
T1: ringcount <= T2;
T2: ringcount <= T3;
T3: ringcount <= T4;
T4: ringcount <= T5;
T5: ringcount <= T6;
T6: ringcount <= T1;
endcase
end
//end of ring counter
/*Mealy state machine in which next state is missing in a sense that
ringcounter indepedently calculate determin it*/
assign state = ringcount;
always @(negedge clk)
case ({state, opcode})
{T1, 4'hx}: cntrl_bus = 12'h5E3; //fetch cycle start here PC > MAR
{T2, 4'hx}: cntrl_bus = 12'hBE3;
{T3, 4'hx}: cntrl_bus = 12'h263; //fetch cycle end here
//LDA operation
{T4, 4'h0}: cntrl_bus = 12'h1A3;
{T5, 4'h0}: cntrl_bus = 12'h2C3;
{T6, 4'h0}: cntrl_bus = 12'h3E3;
//ADD
{T4, 4'h0}: cntrl_bus = 12'h1A3;
{T5, 4'h0}: cntrl_bus = 12'h2E1;
{T6, 4'h0}: cntrl_bus = 12'h3C7;
//SUB
{T4, 4'h0}: cntrl_bus = 12'h1A3;
{T5, 4'h0}: cntrl_bus = 12'h2E1;
{T6, 4'h0}: cntrl_bus = 12'h3EF;
//OUT
{T4, 4'h0}: cntrl_bus = 12'h3F2;
{T5, 4'h0}: cntrl_bus = 12'h3E3;
{T6, 4'h0}: cntrl_bus = 12'h3E3;
//HLT
{T4, 4'h0}: cntrl_bus = 12'h3E3;
{T5, 4'h0}: cntrl_bus = 12'h3E3;
{T6, 4'h0}: cntrl_bus = 12'h3E3;
endcase
endmodule
module sap1main(clk, clr, result, run_prog, ram_sel, Wbus_ext, nLm_ext); //ram_nwr and nCe is placed
in portlist because manually programming will be done
http://technoembed.blogspot.com.br/2014/01/sapsimpleaspossiblecomputermalvino.html 5/7
22/02/2015 SAP simple as possible computer Malvino: Verilog code
input clk, clr, run_prog, ram_sel, nLm_ext;
parameter wordsize = 8;
parameter cntrlbussize = 12;
input [wordsize1:0] Wbus_ext;
output [wordsize1:0] result;
//varibles for run and program mode of SAP1 in FPGA it is connected to the switches
wire ram_nrd, ram_nwr, run_prog, nLm_int;
wire [wordsize1:0] Wbus, Wbus_int;
wire Cp, Ep, nLm, nCe, nLi, nEi, nLa, Ea, Su, Eu, nLb, nLo;
assign nCee = run_prog?nCe:ram_sel;
assign Wbus = run_prog?Wbus_int:Wbus_ext;
assign nLm = run_prog?nLm_int:nLm_ext;
wire [cntrlbussize1:0] cntrl_bus = {Cp, Ep, nLm, nCe, nLi, nEi, nLa, Ea, Su, Eu, nLb, nLo};
wire [wordsize/21:0]opcode;
wire [wordsize1:0] ACC_to_ALU, regB_to_ALU;
pc PC_sap1( Cp, nCLK, nCLR, Ep, Wbus[wordsize/21:0]);
inputMAR MAR_sap1(nLm, clk, in, ram_addr, ram_nrd, ram_nwr, run_prog);
ram ram_sap1(clk, ram_nrd, ram_nwr, nCee, Wbus[wordsize/21:0], Wbus);
IR IR_sap1(clk, nLi, nEi, clr, Wbus, Wbus[wordsize/21:0], opcode);
control_unit cntrl_unit_sap1(clk, clr, cntrl_bus, opcode);
accumulator ACC_sap1(clk, nLa, Ea, Wbus, Wbus, ACC_to_ALU);
addsub(Su, Eu, ACC_to_ALU, regB_to_ALU, Wbus);
regB(nLb, clk, Wbus, ACC_to_ALU);
outreg(nLo, clk, Wbus, result);
endmodule
Read ME for the implementation:
Features
control unit is designed using FSM approach and is designed using Mealy machine
settings
inside sap1main, design is in such a manner that that using FPGA switches you can programm and
execute the SAP1
FPGA settings:
inputs ram_sel, nLm_ext and Wbus_ext are active when run_prog is False ("1'b0")
so programming steps:
1): first clr = ON and then clr = OFF and then run_prog = OFF and nLm_ext = ON
2): apply address at Wbus_ext lower nibble switch pannel
http://technoembed.blogspot.com.br/2014/01/sapsimpleaspossiblecomputermalvino.html 6/7
22/02/2015 SAP simple as possible computer Malvino: Verilog code
3): nLm_ext = OFF
4): now again nLm_ext = ON
5): place required instrunction on Wbus_ext and then ram_sel
6): you are now done with first instruction of your code
7): repeate steps 2 to 6 until your store all your instructions
execution:
steps
1): apply clr signal i.e. clr = ON
2): then clr = OFF
3): run_prog = ON
4): your code is executed and now you can see your result on LED pannel of the result.
Posted 13th January 2014 by Afridi
0 Add a comment
Enter your comment...
Publish Preview Notify me
http://technoembed.blogspot.com.br/2014/01/sapsimpleaspossiblecomputermalvino.html 7/7