Report RISC 16bit
Report RISC 16bit
Report RISC 16bit
ON
By
May 2006
1
A REPORT
ON
By
May 2006
2
ACKNOWLEDGEMENTS
We are very thankful Dr. Chandra Shakhar, Director, CEERI Pilani for giving us an
opportunity to work under her guidance. The love and faith that she showered on us
helped us to go on and complete the project successfully.
We would like to extend our sincere thank to Dr. Anu Gupta, EEE, BITS - Pilani for
their valuable suggestions and guidance, Mr. Pawan Sharma, In-charge OLAB for their
support, Mr. Ninad Kothari, TA, BITS - Pilani for Encouragement.
Last but not the least we would like to thank our Friends, Parents, Family members and
invisible force which provided moral support and spiritual strength, which helped us
completing the work successfully.
3
BIRLA INSTITUTE OF TECHNOLOGY AND SCIENCE
PILANI (Rajasthan) 333031
CERTIFICATE
This is to certify that the project entitled Design of 16 bit RISC Processor
is the bonafide work of Shivananda Reddy (2002A3PS107) done in the
second semester of the academic year 2005-2006. He has duly completed his
project and has fulfilled all the requirements of the course BITS C335,
Computer Laboratory Oriented Project, to my satisfaction.
4
BIRLA INSTITUTE OF TECHNOLOGY AND SCIENCE
PILANI (Rajasthan) 333031
CERTIFICATE
This is to certify that the project entitled Design of 16 bit RISC Processor
is the bonafide work of Raj Kumar Singh Parihar (2002A3PS013) done in
the second semester of the academic year 2005-2006. He has duly completed
his project and has fulfilled all the requirements of the course BITS C335,
Computer Laboratory Oriented Project, to my satisfaction.
5
ABSTRACT
This project includes the designing of 16-Bit RISC processor and modeling of its
components using Verilog HDL. The implementation strategies have been
borrowed from most popular DLX and MIPS architecture up to certain extent.
The instruction set adopted here is extremely simple that gives an insight into the
kind of hardware which should be able to execute the set of instructions properly.
Along with sequential and combinational building blocks of NON- pipelined
processor such as adders and registers more complex blocks i.e. ALU and
Memories had been designed and simulated. The modeling of ALU which has
been done in this project is fully structural starting from half adders. At the end
the semi custom layout had been developed for ALU using AMI05 Technology
and IC station tool. Complex blocks have been modeled using behavioral
approach i.e. Memories, whereas simple blocks i.e. Adders had been done through
structural approach. The tools which had been used throughout the project work
are Modelsim (Digital Simulation), Leonardo Spectrum (Digital synthesis) and
IC station (Digital Semi custom Layout). For synthesis purpose the targeted
FPGA device technology was ALTERA, Cyclone, and EP1C6Q240C. A simple
sequential blocks performance and figure of merits were observed under the
constraints clock frequency: 50 MHz and DRT: 5ns.
6
TABLE OF CONTENTS
ACKNOWLEDGEMENT .......................................................................... 3
CERTIFICATE .................................................................Error! Bookmark not defined.
ABSTRACT.................................................................................................. 6
4. RISC: Top level Description and guidelines ........ Error! Bookmark not
defined.
Bibliography ................................................................................................ 82
7
1. CEERI: An Introduction
1) Semiconductor Devices
2) Microwave Tubes
3) Electronics Systems
The activities of microwave tubes and semiconductor devices areas are done at Pilani
whereas the activities of electronic systems area are undertaken at Pilani as well as the
two other centers at Delhi and Chennai. The institute has excellent computing facilities
with many Pentium computers and SUN/DEC workstations interlined with internet and e-
mail facilities via VSAT. The institute has well maintained library with an outstanding
collection of books and current journals (and periodicals) published all over the world.
CEERI, with its over 700 highly skilled and dedicated staff members, well-equipped
laboratories and supporting infrastructure is ever enthusiastic to take up the challenging
tasks of research and development in various areas.
8
2. RISC: An Introduction
The idea was inspired by the discovery that many of the features that were
included in traditional CPU designs to facilitate coding were being ignored by the
programs that were running on them. Also these more complex features took several
processor cycles to be performed. Additionally, the performance gap between the
processor and main memory was increasing. This led to a number of techniques to
streamline processing within the CPU, while at the same time attempting to reduce the
total number of memory accesses.
When the controller design become more complex in CISC and the performance
was also not up to expectations, people started looking on some other alternatives. It had
been found that when a processor talks to the memory the speed gets killed. So the one
improvement on CPI was to keep the instruction set very simple. Simple in not the way it
works but the way it looks. Thats why we have very few instructions in any typical
RISC architecture where processor asks data from memory probably not other than Load
and Store. We avoid keeping such addressing modes. The complexity of controller design
has been overcome with the help of operands and Opcode bits fixed in instruction
register. At the end the pipelining added a new dimension in the speed just with the help
of some additional registers. Now what pipeline does is it increases throughput by
reducing CPI. The instruction can be executed effectively in one clock cycle. The
pipelining in any kind of architecture took birth from the inherent parallelism and the idle
states of components.
The pipelined architecture could be further enhanced with the concepts known as
super-scaling. There we provide more than one execution unit. The time when one unit is
9
busy with the current execution task, the fetch unit can probably fetch he next instruction
which would be executed with the help of some other execution unit present in system.
uniform instruction encoding (for example the op-code is always in the same bit
position in each instruction, which is always one word long), which allows faster
decoding;
A homogeneous register set, allowing any register to be used in any context and
simplifying compiler design.
simple addressing modes (complex addressing modes are replaced by sequences
of simple arithmetic instructions);
Few data types supported in hardware (for example, some CISC machines had
instructions for dealing with byte strings. Others had support for polynomials and
complex numbers. Such instructions are unlikely to be found on a RISC machine).
Over many years, RISC instruction sets have tended to grow in size. Thus, some have
started using the term "load-store" to describe RISC processors, since this is the key
element of all such designs. Instead of the CPU itself handling many addressing modes,
load-store architecture uses a separate unit dedicated to handling very simple forms of
load and store operations. CISC processors are then termed "register-memory" or
"memory-memory".
Today RISC CPUs (and microcontrollers) represent the vast majority of all CPUs in
use. The RISC design technique offers power in even small sizes, and thus has come to
completely dominate the market for low-power "embedded" CPUs. Embedded CPUs are
by far the largest market for processors. RISC had also completely taken over the market
for larger workstations for much of the 90s. After the release of the Sun SPARCstation
the other vendors rushed to compete with RISC based solutions of their own. Even the
mainframe world is now completely RISC based.
10
3. RISC vs CISC
3.1 CISC Designs
An overriding characteristic of CISC machines is an approach to instruction set
architecture that emphasizes doing more with each instruction. As a result, CISC
machines have a wide variety of addressing modes. CISC machines take a have it your
way approach to the location and number of operands in various instructions. As a result
instructions are of widely varying length and execution times.
As more and more capabilities were added to the processors, it was found
increasingly difficult to support higher clock speeds that would otherwise have been
possible. Complex instructions and addressing modes worked against higher clock
speeds, because of the greater number of microscopic actions that had to be performed
per instruction. Moreover, RAM prices dropped sufficiently so that the pressure on
system designers was less to design instructions that did more that it was to design
systems that were faster. It was also becoming cost-effective to employ small amounts of
higher-speed cache memory to reduce memory latency i.e. the writing time between
when a memory is made and when it has been satisfied.
11
3.3 Why RISC?
Various attempts have been made to increase the instruction execution rates by
overlapping the execution of more than one instruction since the earliest day of
computing. The most common ways of overlapping are pre-fetching, pipelining and
superscalar operation.
12
4. RISC: Top level Description and guidelines
Reset_s1 Input Resets the chip when asserted high. The chip
will switch to the idle state, and fetch from
the main memory starting at address 0.
13
Fig.4 High Level Block Diagram that describes the external interface of the chip
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
ADD 0 0 0 0 Rd Rs Rt
SUB 0 0 0 1 Rd Rs Rt
AND 0 0 1 0 Rd Rs Rt
OR 0 0 1 1 Rd Rs Rt
14
XOR 0 1 0 0 Rd Rs Rt
NOT 0 1 0 1 Rd Rs
SLA 0 1 1 0 Rd Rs
SRA 0 1 1 1 Rd Rs
LI 1 0 0 0 Rd Immediate
LW 1 0 0 1 Rd Rs
SW 1 0 1 0 Rs Rt
BIZ 1 0 1 1 Rs Offset
BNZ 1 1 0 0 Rs Offset
JAL 1 1 0 1 Rd Offset
JMP 1 1 1 0 Offset
JR 1 1 1 1 Rs
15
The Processor features five instruction classes:
ADD: Rd = Rs + Rt
Operands A and B stored in register locations Rs and Rt are added and written to the
destination register specified by Rd.
SUB: Rd = Rs - Rt
Operand B (Rt) is subtracted from Operand A (Rs) and written to Rd.
AND: Rd = Rs & Rt
Operand A (Rs) is bitwise anded with Operand B (Rt) and written into Rd.
OR: Rd = Rs | Rt
Operand A (Rs) is bitwise ored with Operand B (Rt) and written into Rd.
XOR: Rd = Rs ^ Rt
Operand A (Rs) is bitwise Xored with Operand B (Rt) and written into Rd.
NOT: Rd = ~Rs
Operand A (Rs) is bitwise inverted and written into Rd.
SLA: Rd = Rs << 1
Operand A (Rs) is arithmetically shifted to the left by one bit and written into Rd.
SRA: Rd = Rs >> 1
Operand A (Rs) is arithmetically shifted to the right by one bit and written into Rd. The
MSB (sign bit) will be preserved for this operation.
16
The memory word specified by the address in register Rs is loaded into register Rd.
SW: Mem[Rs] = Rt
The data in register Rt is stored into the memory location specified by Rs.
BIZ: PC = PC + 1 + Offset if Rs = 0
If all the bits in register Rs are zero than the current Program Count (PC + 1) is offset to
PC + 1 + Offset. The count is offset from PC + 1 because it is incremented and stored
during the Fetch cycle.
BNZ: PC = PC + 1 + Offset if Rs! = 0
If all the bits in register Rs are not zero than the current Program Count (PC + 1) is offset
to PC + 1 + Offset.
FETCH INSTRUCTION
Part 1
Retrieve instruction word from main memory
Increment Program Counter and store in ALU Out
Part 2
Write Incremented Program Count
Load Operands into latches from Register File
17
EXECUTE INSTRUCTION
Part 1
Perform ALU Operation based instruction word and store in ALU Out
Move Memory Word into MDR for Load Word operation
Write Data into Memory from Register File for Store Word operation
Part 2
Write ALU, IR (Immediate), or MDR data into Register File
Write new Program Count for Jump Operation or it Branch taken
4.2 MICRO-ARCHITECTURE
The micro-architecture refers to a view of the machine that exposes the registers,
buses and all other important functional units such as ALUs and counters. The principle
subsystems of a processor are the CPU, main memory and the input/output. The data path
and the control unit interact to do the actual processing task. The control unit receives
signals from the data path and sends control signals to the data oath. These signal s
control the data flow within the CPU and between the CPU and the main memory and
Input/Output.
Program Counter
18
Instruction Register and Register File
19
ALU and Operand Registers
The Control FSM has only three distinct states that determine the operation of the
processor: IDLE, FETCH and EXECUTE. Here fetch and Execute is further divided into
two states, Fetch instruction state and Fetch operands state. Similarly Execute state also
divided into two parts. When the reset signal (reset_s1) goes high from any state, the
FSM will be placed in the IDLE state. While in the IDLE state the control unit will send
the PC write enable signal (pc_wrt_s2 = 1) and select zero (pc_sel_s2 = 0) as the current
Program count.
20
When the reset signal goes low, the FSMs next state will be the FETCH state and
the instruction from Memory address 0 will be loaded into the Instruction Register (IR) to
begin program execution. The control looks at the next state = FETCH and generates the
IR write (ir_wrt_s1), Operand A Select (opA_sel_s1), Operand B Select (opB_sel_s1 =
0010) and the ALU add operation (alu_op_s1 = 00000001) to load the IR with the next
instruction and increment the PC by 1. These events all occur on the first clock of the
FETCH state. One-hot signals are used for alu_op_s1, opB_sel_s1, and data_sel_s2 to
make for easier decoding in the datapath units. The operation at the next phase of FETCH
will be determined by the opcode (opcode_s2) from the IR, except for the incremented
PC that is written in from the ALU ouput latch in all cases. The ALU Operations will
load in Operands A and B from the Register File. The Load word will only need Operand
A, while the Store word will need both operands (one for the address and one for the data
word). The Branch instructions will use the offset in its instruction word and PC + 1
count as operands into the ALU. The JAL stores the incremented PC in the Register File,
while the JR loads the return address into Operand A.
After phase two of the FETCH state, the FSM enters the EXECUTE state. During
the first phase for an ALU operation, the appropriate alu_op_s1 control signals are sent to
the ALU as decoded from the opcode. The operand mux (opA_sel_s1 & opB_sel_s1)
control signals are also generated to select the latch outputs. For the other operations
(except LI), an add operation is required from the ALU. The operands chosen for the add
are determined by the operation specified. The Load and Store words will access Memory
on this first phase as well. The second phase of EXECUTE writes data into the register
file or writes a new address into the PC. For the branch instruction, the control will look
at the check zero signal from operand A to determine if the branch should be taken and
the new PC should be written. The control returns the next state to FETCH to repeat the
process for the next instruction.
(All the source codes are included in appendix section)
21
5. Design and Simulation: Building Blocks
Code:
//d flip flops : Behavioral model
module dff_bhv(dout,din,clk,reset,set);
input reset,set,clk,din;
output dout;
reg dout;
Simulation:
(Waveform Analyzer window)
Synthesis:
(Typical Value)
Clock Frequency: 50 MHz (only for Sequential Circuits)
Data Required Time: 5ns
(Optimization Report)
22
Slack is a High positive value for DRT = 5ns
new DRT = 3ns
(Delay Report)
(RTL Schematic)
23
(Report Area)
24
(Critical Path Schematic)
(Technology Schematic)
Conclusion:
Data required time is = 3ns
For this value of DRT the slack is = 0.53
25
5.2 Combinational Element: N-Bit add-subtract Module
Structural model of a N-Bit adder sub-tractor module with overflow detection techniques
using 1-Bit full adder
xor xor1(sum,ain,bin);
and and1(carry,ain,bin);
endmodule
Simulation:
(Workspace: Design Hierarchy)
(Simulation window)
26
Synthesis:
Data Required Time: 5ns
(Optimization Report)
(Area Report)
27
(Delay Report)
(RTL Schematic)
Conclusion:
Logic cells used = 2
Maximum path delay = 4ns
Input ports = 3
output ports = 2
28
PART - B
// 8-bit adder and sub: using full adders and xor
module add_sub_8b(o_flag,cout,sum,ain,bin,ctrl);
input [7:0]ain;
input [7:0]bin;
input ctrl;
output cout,o_flag;
output [7:0]sum;
wire [7:0] w;
wire [6:0] c;
xor x0(w[0],bin[0],ctrl),
x1(w[1],bin[1],ctrl),
x2(w[2],bin[2],ctrl),
x3(w[3],bin[3],ctrl),
x4(w[4],bin[4],ctrl),
x5(w[5],bin[5],ctrl),
x6(w[6],bin[6],ctrl),
x7(w[7],bin[7],ctrl);
full_adder fa1(c[0],sum[0],ain[0],w[0],ctrl),
fa2(c[1],sum[1],ain[1],w[1],c[0]),
fa3(c[2],sum[2],ain[2],w[2],c[1]),
fa4(c[3],sum[3],ain[3],w[3],c[2]),
fa5(c[4],sum[4],ain[4],w[4],c[3]),
fa6(c[5],sum[5],ain[5],w[5],c[4]),
fa7(c[6],sum[6],ain[6],w[6],c[5]),
fa8(cout,sum[7],ain[7],w[7],c[6]);
xor x(o_flag,c[6],cout);
endmodule
Simulation:
(Waveform Analyzer window)
Synthesis:
29
(Optimization Report)
(Delay Report)
Conclusion:
30
(RTL Schematic)
31
6. ASIC Design Flow: Design of a 16-Bit ALU
Objective:
Design a 16-Bit Arithmetic Logic unit (ALU) which can perform arithmetic and bit-wise
logical operations.
Parts are as following
1.Arithmetic unit
A-Logic
B-Logic
16-Bit Adder
1-Bit Full Adder
2.Logic Operation unit
3.output MUX
4.Status Register
Operation Summary:
Code:
//Code Starts from here
//alu version -2 fully str..and fully optimized <str> : (\/)
module alu_16bit(c,v,z,n,result,parity,m,sel,cout,ain,bin,c0);
input [15:0] ain,bin;
input m,c0;
input [1:0] sel;
32
b_logic b1(sel,b_in,bin);
a_logic a1 (sel,a_in,ain);
adder_16 add1(parity,cout,ari_out,a_in,b_in,c0);
logic_unit l1(res_out,sel,ain,bin);
//s_logic
slogic1(status[0],status[1],status[2],status[3],result,cout,o_flow,m);
assign z = ~(result[0] & result[1] & result[2] & result[3] & result[4]
& result[5] & result[6] & result[7] & result[8]
& result[9] & result[10] & result[11] & result[12] &
result[13] & result[14] & result[15]);
assign n = result [15];
assign v = cout ^ result[15];
assign c = cout;
endmodule
logic_low_unit
llu0(and_out[0],or_out[0],xor_out[0],xnor_out[0],ain[0],bin[0]),
llu1(and_out[1],or_out[1],xor_out[1],xnor_out[1],ain[1],bin[1]),
llu2(and_out[2],or_out[2],xor_out[2],xnor_out[2],ain[2],bin[2]),
llu3(and_out[3],or_out[3],xor_out[3],xnor_out[3],ain[3],bin[3]),
llu4(and_out[4],or_out[4],xor_out[4],xnor_out[4],ain[4],bin[4]),
llu5(and_out[5],or_out[5],xor_out[5],xnor_out[5],ain[5],bin[5]),
llu6(and_out[6],or_out[6],xor_out[6],xnor_out[6],ain[6],bin[6]),
llu7(and_out[7],or_out[7],xor_out[7],xnor_out[7],ain[7],bin[7]),
llu8(and_out[8],or_out[8],xor_out[8],xnor_out[8],ain[8],bin[8]),
llu9(and_out[9],or_out[9],xor_out[9],xnor_out[9],ain[9],bin[9]),
llu10(and_out[10],or_out[10],xor_out[10],xnor_out[10],ain[10],bin[10]),
llu11(and_out[11],or_out[11],xor_out[11],xnor_out[11],ain[11],bin[11]),
llu12(and_out[12],or_out[12],xor_out[12],xnor_out[12],ain[12],bin[12]),
llu13(and_out[13],or_out[13],xor_out[13],xnor_out[13],ain[13],bin[13]),
llu14(and_out[14],or_out[14],xor_out[14],xnor_out[14],ain[14],bin[14]),
llu15(and_out[15],or_out[15],xor_out[15],xnor_out[15],ain[15],bin[15]);
mux_4by1 mux41(res_out,sel,and_out,or_out,xor_out,xnor_out);
endmodule
33
// 4 by 1 mux : <str> (\/)
module mux_4by1(out,sel,i0,i1,i2,i3);
input [15:0] i0,i1,i2,i3;
output [15:0] out;
input [1:0] sel;
reg [15:0] out;
always @ (i0 or i1 or i2 or i3 or sel)
case (sel)
2'b00: out=i0;
2'b01: out=i1;
2'b10: out=i2;
2'b11: out=i3;
endcase
endmodule
nand aand1(w1,ain,bin);
not nnot1(and_out,w1);
nor oor1(w2,ain,bin);
not nnot11(or_out,w2);
or oor2(xnor_out,and_out,w2);
not nnot2(xor_out,xnor_out);
endmodule
b_logic_low bl0(sel,bout[0],bin[0]),
bl1(sel,bout[1],bin[1]),
bl2(sel,bout[2],bin[2]),
bl3(sel,bout[3],bin[3]),
bl4(sel,bout[4],bin[4]),
bl5(sel,bout[5],bin[5]),
34
bl6(sel,bout[6],bin[6]),
bl7(sel,bout[7],bin[7]),
bl8(sel,bout[8],bin[8]),
bl9(sel,bout[9],bin[9]),
bl10(sel,bout[10],bin[10]),
bl11(sel,bout[11],bin[11]),
bl12(sel,bout[12],bin[12]),
bl13(sel,bout[13],bin[13]),
bl14(sel,bout[14],bin[14]),
bl15(sel,bout[15],bin[15]);
endmodule
35
full_adder fulla0(c[0],sum[0],ain[0],bin[0],cin),
fulla1(c[1],sum[1],ain[1],bin[1],c[0]),
fulla2(c[2],sum[2],ain[2],bin[2],c[1]),
fulla3(c[3],sum[3],ain[3],bin[3],c[2]),
fulla4(c[4],sum[4],ain[4],bin[4],c[3]),
fulla5(c[5],sum[5],ain[5],bin[5],c[4]),
fulla6(c[6],sum[6],ain[6],bin[6],c[5]),
fulla7(c[7],sum[7],ain[7],bin[7],c[6]),
fulla8(c[8],sum[8],ain[8],bin[8],c[7]),
fulla9(c[9],sum[9],ain[9],bin[9],c[8]),
fulla10(c[10],sum[10],ain[10],bin[10],c[9]),
fulla11(c[11],sum[11],ain[11],bin[11],c[10]),
fulla12(c[12],sum[12],ain[12],bin[12],c[11]),
fulla13(c[13],sum[13],ain[13],bin[13],c[12]),
fulla14(c[14],sum[14],ain[14],bin[14],c[13]),
fulla15(cout,sum[15],ain[15],bin[15],c[14]);
assign cp =
(sum[0]^sum[1]^sum[2]^sum[3]^sum[4]^sum[5]^sum[6]^sum[7]^sum[8]^sum[9]^
sum[10]^sum[11]^sum[12]^sum[13]^sum[14]^sum[15]);
endmodule
Simulation:
(Workspace Window: Hierarchy in Design)
(Simulation Window)
36
Logical Operations:
Arithmetic Operation:
37
Synthesis:
(Typical Value)
Clock Frequency: 50 MHz (only for Sequential Circuits)
Data Required Time: 20ns
(Optimization Report)
38
(RTL Schematic)
39
Semi -Custom Layout:
40
(ALU: Layout after Routing)
41
(PEX: SPICE NETLIST)
* File: alu.pex.netlist
* Created: Thu Apr 20 21:38:03 2006
* Program "Calibre xRC"
* Version "v9.3_5.11"
*
.subckt ALU AIN[10] AIN[12] AIN[11] SEL[0] BIN[10] BIN[11] BIN[12] AIN[13]
+ BIN[13] AIN[14] RESULT[13] RESULT[11] RESULT[10] RESULT[12] RESULT[8] RESULT[9]
+ BIN[14] BIN[9] RESULT[14] N PARITY C AIN[9] V AIN[15] AIN[8] BIN[15] BIN[8] M
+ SEL[1] Z BIN[7] AIN[1] AIN[7] BIN[1] AIN[6] RESULT[7] BIN[0] RESULT[6] AIN[0]
+ RESULT[5] RESULT[4] BIN[6] C0 RESULT[1] AIN[5] BIN[5] AIN[2] RESULT[0] BIN[2]
+ RESULT[2] RESULT[3] AIN[3] AIN[4] BIN[4] BIN[3] VDD GND
*
mM0 VDD 269 Z VDD p L=6e-07 W=2.7e-06 AD=9.72e-12 AS=3.555e-12
mM1 270 104 VDD VDD p L=6e-07 W=5.4e-06 AD=4.86e-12 AS=9.72e-12
mM2 271 94 270 VDD p L=6e-07 W=5.4e-06 AD=4.86e-12 AS=4.86e-12
mM3 272 153 271 VDD p L=6e-07 W=5.4e-06 AD=4.86e-12 AS=4.86e-12
mM4 269 155 272 VDD p L=6e-07 W=5.4e-06 AD=8.235e-12 AS=4.86e-12
mM5 GND 269 Z GND n L=6e-07 W=1.5e-06 AD=2.475e-12 AS=2.475e-12
mM6 GND 104 269 GND n L=6e-07 W=1.5e-06 AD=2.7e-12 AS=2.475e-12
mM7 269 94 GND GND n L=6e-07 W=1.5e-06 AD=2.7e-12 AS=2.7e-12
....................................................................................................
...................................................................................................
...................................................................................................
....................................................................................................
...................................................................................................
...................................................................................................
42
7. Implementation: 16-Bit Non-pipelined RISC Processor
Register Set:
1. R - Format
Instructions:
Opcode Function(Men) ALU_task
0h ADD 0h
43
0h SUB 1h
0h AND 2h
0h OR 3h
0h XOR 4h
0h SHL 5h
0h SHR 6h
0h ROT 7h
1. I -Format
REG <-- [REG], [IMME_VAL] : Arithmetic and Logical operations
OPCODE DST SRC IMM_VAL
IR[19:16] IR[15:12] IR[11:8] IR[7:0]
Size:
4B 4B 4B 8B
Instructions:
Opcode Function(Men) ALU_task
1h ADDi x
2h SUBi x
3h ANDi x
4h ORi x
5h XORi x
6h SHLi x
7h SHRi x
8h ROTi x
9h LW(i) x
10h SW(i) x
Fh BRz x
J- Format
PC <- Address:
Opcode Address
IR[19:16] IR[15:0]
Size:
4B 16B
Instructions:
JMP [Address]
44
Code:
wire [15:0]AOUT;
wire [3:0]opcode,alu_task,alu_fun;
wire cout,aluout_ctrl,npc_ctrl,ir_ctrl,A_ctrl,B_ctrl,lmd_ctrl,imm_ctrl,
sel_mxa, sel_mxb, sel_mxout,write,memwr,memrd,cond_ctrl,wr_data_ins,rd_data_ins;
control_unit controlpath(
clk,reset,AOUT,cout,opcode,alu_fun,aluout_ctrl,npc_ctrl,ir_ctrl,A_ctrl,B_ctrl,lmd_ctrl,imm_ctrl,
sel_mxa, sel_mxb, sel_mxout,write,memwr,memrd,alu_task,cond_ctrl,wr_data_ins,rd_data_ins);
risc_nonpipe datapath(
AOUT,cout,opcode,alu_fun,aluout_ctrl,clk,reset,npc_ctrl,ir_ctrl,A_ctrl,B_ctrl,lmd_ctrl,imm_ctrl,
sel_mxa, sel_mxb,
sel_mxout,write,memwr,memrd,alu_task,cond_ctrl,wr_data,wr_data_ins,rd_data_ins);
endmodule
//Datapath
45
module risc_nonpipe (
AOUT,cout,opcode,alu_fun,aluout_ctrl,clk,reset,npc_ctrl,ir_ctrl,A_ctrl,B_ctrl,lmd_ctrl,imm_ctrl,
sel_mxa, sel_mxb,
sel_mxout,write,memwr,memrd,alu_task,cond_ctrl,wr_data,wr_data_ins,rd_data_ins);
input aluout_ctrl,clk,reset,npc_ctrl,ir_ctrl,A_ctrl,B_ctrl,lmd_ctrl,imm_ctrl,
sel_mxa, sel_mxb, sel_mxout,write,memwr,memrd,cond_ctrl,wr_data_ins,rd_data_ins;
input [3:0]alu_task;
output cout;
output [3:0] opcode,alu_fun;
output [15:0] AOUT;
output [19:0] wr_data;
pc pcreg(clk,reset,pc_out,pc_in);
adder16 pc_adder(npc_in,pc_out,16'h1);
//NPC
latch16 NPC(npc_ctrl,npc_out,npc_in);
//IR
IR ir_reg(ir_ctrl,opcode,dst,src1,src2,alu_fun,ins_out);
//A
latch16 A(A_ctrl,a_out,a_in);
//B
latch16 B(B_ctrl,b_out,b_in);
//LMD
latch16 LMD(lmd_ctrl,lmd_out,lmd_in);
//IMM
latch16 IMM(imm_ctrl,imm_out,imm_in);
//COND
//cond COND1(cond_ctrl,sel_cond,cond_in);
alu16 alu(cout,aluout_in,alu_src1,alu_src2,alu_task);
//ALU_OUT
latch16 ALU_OUT(aluout_ctrl,aluout_out,aluout_in);
data_mem datamem(lmd_in,aluout_out,b_out,memwr,memrd);
//ins_mem insmem(ins_out,pc_out);
ins_mem insmem(ins_out,pc_out,wr_data,wr_data_ins,rd_data_ins);
mux2x1_16b muxa(sel_mxa,alu_src1,npc_out,a_out),
muxb(sel_mxb,alu_src2,b_out,imm_out),
muxnpc_alu(cond_ctrl,pc_in,npc_out,aluout_out),
muxout(sel_mxout,reg_wr_in,lmd_out,aluout_out);
46
sign_xtnd xtender(src2,alu_fun, imm_in);
//reg_file reg_Ro_R15(write,a_in,b_in,src1,src2,dst,reg_wr_in);
reg_file_2p reg_Ro_R15(clk,write,a_in,b_in,src1,src2,dst,reg_wr_in);
//brz_check iszero(a_out,cond_in);
//Adder - 16 Bit
module adder16 (addout,ain,bin);
input [15:0] ain,bin;
output [15:0] addout;
47
//Alu - 16 Bit
module alu16(cout,aluout,ain,bin,alu_func);
input [15:0] ain,bin;
input [3:0] alu_func;
output [15:0] aluout;
output cout;
reg [15:0] aluout;
reg cout;
case(alu_func)
4'b0000: {cout,aluout} = ain+bin;
4'b0001: {cout,aluout} = ain-bin;
module reg_file_2p(clk,write,rdata1,rdata2,rdreg1,rdreg2,wrreg,wr_data);
input [3:0] rdreg1,rdreg2,wrreg;
input [15:0] wr_data;
48
input write,clk;
output [15:0] rdata1,rdata2;
reg [15:0] rdata1,rdata2;
//IR Latch
49
module IR (ctrl,opcode,dst,src1,src2,alu_fun,ir_in);
input [19:0] ir_in;
input ctrl;
output [3:0]opcode,dst,src1,src2,alu_fun;
reg [3:0]opcode,dst,src1,src2,alu_fun;
//output [19:0] ir_out;
//reg [19:0] ir_out;
//CondLatch
module cond (ctrl,cond_out,cond_in);
input cond_in;
input ctrl;
output cond_out;
reg cond_out;
//Instruction memery
module ins_mem(rd_data,address,wr_data,memwr,memrd);
input [15:0] address;
input [19:0] wr_data;
input memwr,memrd;
output [19:0]rd_data;
reg [19:0]rd_data;
reg [19:0] mem_data[0:31];
else
rd_data = 20'bzzzzzzzzzzzzzzzz;
end
endmodule
//Data memory
50
module data_mem(rd_data,address,wr_data,memwr,memrd);
input [15:0] address, wr_data;
input memwr,memrd;
output [15:0]rd_data;
reg [15:0]rd_data;
reg [15:0] mem_data [0:31];
else
rd_data = 16'bzzzzzzzzzzzzzzzz;
end
endmodule
Simulation:
(Workspace)
51
(Signal Window)
52
(Register Bank): R0 to R15 [16-Bit each]
53
(Simulation Window)
Synthesis:
Without optimization: Implementation Report
54
DATA - PATH
(Page: 1)
(Page: 2)
55
Basic Building Blocks of DATAPATH
1. Control Unit
56
2. Program Counter
3. 16-Bit Adder
4. 16-Bit Latch
5. Instruction Register
57
7. Data Memory
8. Instruction Memory
9. Mux 2 x 1
58
12. RISC-Data Path
59
ALU with MUX-ed Inputs
(Optimization Report)
60
(Delay Report)
(Area Report)
61
Critical path Schematic
62
Appendix - I
DATA Path Schematic
63
Appendix II
Controller State Diagram
64
Appendix III
Verilog Codes - RTL code for RISC design with a micro-coded control unit
//************************************************************
// Top level ModuleRISC.v
module risc(clk,reset);
input clk,reset;
wire [3:0]opcode;
wire [2:0] alu_sel;
wire [1:0] opb_sel,data_sel;
wire [15:0] outA;
wire carry,pc_sel,pc_wrt,addr_sel,ir_wrt,rega_sel,reg_wrt,opa_sel,re,we;
control_unit control_path(opcode,outA,carry,reset,pc_sel,pc_wrt,addr_sel,
ir_wrt,data_sel,rega_sel,
reg_wrt,opb_sel,opa_sel,
alu_sel,re,we,clk);
output pc_sel,pc_wrt,addr_sel,ir_wrt,rega_sel,reg_wrt,opa_sel,re,we;
output [1:0] data_sel,opb_sel;
output [2:0] alu_sel;
reg pc_sel,pc_wrt,addr_sel,ir_wrt,rega_sel,reg_wrt,opa_sel,re,we;
reg [1:0] data_sel,opb_sel;
reg [2:0] alu_sel;
65
assign alu_task = opcode;
parameter start=3'b100,s0=3'b000,s1=3'b001,s2=3'b010,s3=3'b011;
s0: nstate=s1;
s1: nstate=s2;
s2: nstate=s3;
s3: nstate=s0;
endcase
66
re=1;
we=0;
data_sel=2'b00;
opb_sel=2'b00;
alu_sel=3'b000; end
//*****************************************************
s1: begin
//write incremented Program Count
//Load Operands into Latches from Register File
case(opcode)
4'b0xxx: begin
pc_sel=1;
pc_wrt=1;
addr_sel=0;
ir_wrt=0;
rega_sel=0;
reg_wrt=0;
opa_sel=0;
re=0;
we=0;
data_sel=2'b00;
opb_sel=2'b00;
alu_sel=alu_task; end
4'b1000: begin// Load Immediate word
pc_sel=1;
pc_wrt=1;
addr_sel=0;
ir_wrt=0;
rega_sel=1;
reg_wrt=0;
opa_sel=0;
re=0;
we=0;
data_sel=2'b00;
opb_sel=2'b11;
alu_sel=3'b000; end
4'b1001: begin// Load Word Operation
pc_sel=1;
pc_wrt=1;
addr_sel=0;
ir_wrt=0;
rega_sel=0;
reg_wrt=0;
opa_sel=0;
re=0;
we=0;
data_sel=2'b00;
opb_sel=2'b00;
alu_sel=3'b000; end
4'b1010: begin//Store Word Operation Keep 11:8 0000
pc_sel=1;
67
pc_wrt=1;
addr_sel=0;
ir_wrt=0;
rega_sel=0;
reg_wrt=0;
opa_sel=0;
re=0;
we=0;
data_sel=2'b00;
opb_sel=2'b00;
alu_sel=3'b000; end
4'b1011: begin//Branch If zero
pc_sel=1;
pc_wrt=1;
addr_sel=0;
ir_wrt=0;
rega_sel=0;
reg_wrt=0;
opa_sel=0;
re=0;
we=0;
data_sel=2'b00;
opb_sel=2'b00;
alu_sel=000; end
4'b1100: begin//Branch if Not zero
pc_sel=1;
pc_wrt=1;
addr_sel=0;
ir_wrt=0;
rega_sel=0;
reg_wrt=0;
opa_sel=0;
re=0;
we=0;
data_sel=2'b00;
opb_sel=2'b00;
alu_sel=000; end
4'b1101: begin//Jump and link
pc_sel=1;
pc_wrt=1;
addr_sel=0;
ir_wrt=0;
rega_sel=0;
reg_wrt=1;
opa_sel=0;
re=0;
we=0;
data_sel=2'b10;
opb_sel=2'b00;
alu_sel=000; end
4'b1110: begin//Simple Jump
68
pc_sel=1;
pc_wrt=1;
addr_sel=0;
ir_wrt=0;
rega_sel=0;
reg_wrt=0;
opa_sel=0;
re=0;
we=0;
data_sel=2'b10;
opb_sel=2'b00;
alu_sel=000; end
4'b1111: begin//Jump Return-- PC = Rs
pc_sel=1;
pc_wrt=1;
addr_sel=0;
ir_wrt=0;
rega_sel=0;
reg_wrt=0;
opa_sel=0;
re=0;
we=0;
data_sel=2'b10;
opb_sel=2'b00;
alu_sel=000; end
endcase
end
//*****************************************************
s2: begin
//Perform ALU Operation based instruction word and store in ALU Out
//Move Memory Word into MDR for Load Word operation
//Write Data into Memory from Register File for Store Word operation
case(opcode)
4'b0xxx: begin
pc_sel=1;
pc_wrt=0;
addr_sel=0;
ir_wrt=0;
rega_sel=0;
reg_wrt=0;
opa_sel=0;
re=0;
we=0;
data_sel=2'b00;
opb_sel=2'b00;
alu_sel=alu_task; end
4'b1000: begin // Load Immediate word operation
pc_sel=1;
pc_wrt=0;
addr_sel=1;
ir_wrt=0;
69
rega_sel=0;
reg_wrt=0;
opa_sel=0;
re=0;
we=1;
data_sel=2'b01;
opb_sel=2'b00;
alu_sel=3'b000; end
4'b1001: begin// Load Word Operation
pc_sel=1;
pc_wrt=0;
addr_sel=1;
ir_wrt=0;
rega_sel=1;
reg_wrt=0;
opa_sel=1;
re=0;
we=0;
data_sel=2'b01;
opb_sel=2'b00;
alu_sel=3'b000; end
4'b1010: begin//Store Word Operation Keep 11:8 0000
pc_sel=1;
pc_wrt=0;
addr_sel=0;
ir_wrt=0;
rega_sel=0;
reg_wrt=0;
opa_sel=0;
re=0;
we=0;
data_sel=2'b01;
opb_sel=2'b00;
alu_sel=3'b000; end
4'b1011: begin//Branch If Zero
pc_sel=1;
pc_wrt=0;
addr_sel=0;
ir_wrt=0;
rega_sel=1;
reg_wrt=0;
opa_sel=zero;
re=0;
we=0;
data_sel=2'b00;
opb_sel=2'b11;
alu_sel=000; end
4'b1100: begin//Branch If not Zero
pc_sel=1;
pc_wrt=0;
addr_sel=0;
70
ir_wrt=0;
rega_sel=1;
reg_wrt=0;
opa_sel=~zero;
re=0;
we=0;
data_sel=2'b00;
opb_sel=2'b11;
alu_sel=000; end
4'b1101: begin//Jump and Link
pc_sel=1;
pc_wrt=0;
addr_sel=0;
ir_wrt=0;
rega_sel=1;
reg_wrt=0;
opa_sel=1;
re=0;
we=0;
data_sel=2'b00;
opb_sel=2'b11;
alu_sel=000; end
4'b1110: begin// Simple Jump
pc_sel=1;
pc_wrt=0;
addr_sel=0;
ir_wrt=0;
rega_sel=1;
reg_wrt=0;
opa_sel=1;
re=0;
we=0;
data_sel=2'b00;
opb_sel=2'b11;
alu_sel=000; end
4'b1111: begin// Jump Return
pc_sel=1;
pc_wrt=0;
addr_sel=0;
ir_wrt=0;
rega_sel=0;
reg_wrt=0;
opa_sel=0;
re=0;
we=0;
data_sel=2'b00;
opb_sel=2'b00;
alu_sel=000; end
endcase
end
//*****************************************************
71
s3: begin
//Write ALU, IR (Immediate), or MDR data into Register File
//Write new Program Count for Jump Operation or it Branch taken
case(opcode)
4'b0xxx: begin
pc_sel=1;
pc_wrt=0;
addr_sel=1;
ir_wrt=0;
rega_sel=0;
reg_wrt=1;
opa_sel=0;
re=0;
we=0;
data_sel=2'b00;
opb_sel=2'b00;
alu_sel=alu_task; end
4'b1000: begin // Load Immediate word
pc_sel=1;
pc_wrt=0;
addr_sel=1;
ir_wrt=0;
rega_sel=1;
reg_wrt=1;
opa_sel=0;
re=1;
we=0;
data_sel=2'b01;
opb_sel=2'b11;
alu_sel=3'b000; end
4'b1001: begin// Load Word Operation
pc_sel=1;
pc_wrt=0;
addr_sel=1;
ir_wrt=0;
rega_sel=1;
reg_wrt=1;
opa_sel=1;
re=1;
we=0;
data_sel=2'b01;
opb_sel=2'b11;
alu_sel=3'b000; end
4'b1010: begin//Store Word Operation Keep 11:8 0000
pc_sel=1;
pc_wrt=0;
addr_sel=0;
ir_wrt=0;
rega_sel=0;
reg_wrt=0;
opa_sel=0;
72
re=0;
we=0;
data_sel=2'b01;
opb_sel=2'b00;
alu_sel=3'b000; end
4'b1011: begin//Branch If Zero
pc_sel=1;
pc_wrt=zero;
addr_sel=0;
ir_wrt=0;
rega_sel=1;
reg_wrt=0;
opa_sel=zero;
re=0;
we=0;
data_sel=2'b00;
opb_sel=2'b11;
alu_sel=000; end
4'b1100: begin//Branch if not zero
pc_sel=1;
pc_wrt=~zero;
addr_sel=0;
ir_wrt=0;
rega_sel=1;
reg_wrt=0;
opa_sel=zero;
re=0;
we=0;
data_sel=2'b00;
opb_sel=2'b11;
alu_sel=000; end
4'b1101: begin//Jump and Link
pc_sel=1;
pc_wrt=1;
addr_sel=0;
ir_wrt=0;
rega_sel=1;
reg_wrt=0;
opa_sel=1;
re=0;
we=0;
data_sel=2'b00;
opb_sel=2'b11;
alu_sel=000; end
4'b1110: begin//Simple Jump
pc_sel=1;
pc_wrt=1;
addr_sel=0;
ir_wrt=0;
rega_sel=1;
reg_wrt=0;
73
opa_sel=1;
re=0;
we=0;
data_sel=2'b00;
opb_sel=2'b11;
alu_sel=000; end
4'b1111: begin//Jump Return
pc_sel=1;
pc_wrt=1;
addr_sel=0;
ir_wrt=0;
rega_sel=0;
reg_wrt=0;
opa_sel=0;
re=0;
we=0;
data_sel=2'b00;
opb_sel=2'b00;
alu_sel=000; end
endcase
end
endcase
endmodule
//************************************************************
//Data path Design
module datapath( irout,outA,carry,pc_sel,pc_wrt,addr_sel,
ir_wrt,data_sel,rega_sel,
reg_wrt,opb_sel,opa_sel,
alu_sel,re,we,clk,rst);
input pc_sel,pc_wrt,addr_sel,ir_wrt,
rega_sel,reg_wrt,opa_sel,re,we,rst;
input [1:0] data_sel,opb_sel;
input [2:0] alu_sel;
input clk;
output [3:0] irout;
output [15:0] outA;
output carry;
wire pc_sel,pc_wrt,addr_sel,ir_wrt,
rega_sel,reg_wrt,opa_sel;
wire [1:0] data_sel,opb_sel;
wire [2:0] alu_sel;
wire [3:0] instr15_12,instr11_8,instr7_4,instr3_0, rega;
wire [15:0] outA,alu_out,alu_rslt,pcin,pcout,address,data_in,data_out,sign_ext8,datain,
offsetdata,memout,opa,Ra,adata,Rb,bdata,opb;
wire [15:0]zero,one;
74
wire clk;
mux4b_2_to_1 instrmux(instr11_8,instr7_4,rega_sel,rega);
regfile16 regfile(rega,Ra,instr3_0,Rb,instr11_8,datain,reg_wrt,address,data_in,clk);
signextender signext(instr7_4,instr3_0,sign_ext8);
mdr memory_data_reg(data_out,memout,clk);
mux4_to_1 opbmux(sign_ext8,memout,alu_rslt,zero,data_sel,datain);
opa registera(Ra,adata,clk);
opb registerb(Rb,bdata,clk);
offset offsetpart(sign_ext8,offsetdata,clk);
mux2_to_1 regamux(adata,pcout,opa_sel,opa);
mux4_to_1 regbmux(bdata,zero,one,offsetdata,opb_sel,opb);
alu16b alu(opa,opb,alu_sel,alu_out,carry);
aluout finalout(alu_out,alu_rslt,clk);
endmodule
//************************************************************
//ALU Behavioural
module alu16b(PORT1, PORT2, ALUCON, ALUOUT, carry);
input [15:0]PORT1,PORT2;
begin
case (ALUCON[2:0])
75
3'b000 : begin
{temp,ALUOUT} = (PORT1 + PORT2); //do add
//generate appropriate carry for the purpose of slt especially
if(PORT1[15]==PORT2[15])
carry=temp;
else
if(PORT1[15]==1)
carry=1;
else
carry=0;
end
3'b001 : begin
{temp,ALUOUT} = (PORT1 - PORT2); // do subtract
//generate appropriate carry for the purpose of slt especially
if(PORT1[15]==PORT2[15])
carry=temp;
else
if(PORT1[15]==1)
carry=1;
else
carry=0;
end
3'b010 : begin ALUOUT = PORT1 & PORT2;temp=0;carry=0; end // do and operation
3'b011 : begin ALUOUT = PORT1 | PORT2;temp=0;carry=0; end // do or operation
3'b100 : begin ALUOUT = PORT1 ^ PORT2;temp=0;carry=0; end // do xor operation
3'b101 : begin ALUOUT = ~PORT1 ;temp=0;carry=0; end // do not operation
3'b110 : begin ALUOUT = PORT1 << 1;temp=0;carry=0; end // do SLA operation
3'b111 : begin ALUOUT = PORT1 >> 1;temp=0;carry=0; end // do SRA operation
endcase
end
endmodule
//************************************************************
//Register File which contains 16 Register of 16 bits
module regfile16(add_Rs, out_Rs, add_Rt, out_Rt, add_Rd, data_wr, regwr,addr_sw,data_sw,
clk) ;
76
assign data_sw = out_Rt;
if(regwr)
begin
if (add_Rd == 0)
Register[add_Rd] = 0;//if it is zero ,the output must be zero only
else
Register[add_Rd] = data_wr;
$display("At this posedge Register %d of Regfile is written %h",add_Rd,data_wr);
end
endmodule
//************************************************************
module ram (clk, address, data_in, data_out, re, we);
//parameter DATA_WIDTH = 16 ;
//parameter ADDR_WIDTH = 16 ;
//parameter RAM_DEPTH = 1 << ADDR_WIDTH;
//--------------Input Ports-----------------------
input clk ;
input [15:0] address, data_in ;
input re ;
input we ;
//--------------Inout Ports-----------------------
output [15:0] data_out ;
//--------------Internal variables----------------
reg [15:0] data ;
reg [15:0] mem [15:0];//65535
77
// Memory Write Block
// Write Operation : When we = 1
always @ (posedge clk)
begin : MEM_WRITE
if ( we ) begin
mem[address] = data_in;
end
end
endmodule
//************************************************************
module instr_reg(instr_data,irwr, clk,instr15_12, instr11_8, instr7_4, instr3_0);
input [15:0] instr_data;
input irwr,clk;
output [3:0] instr15_12, instr11_8, instr7_4, instr3_0;
//************************************************************
module pc(indata,outdata,pc_wrt_s2,rst,clk);
input [15:0]indata;
input clk,pc_wrt_s2,rst;
output [15:0] outdata;
reg [15:0] outdata;
always @ (posedge clk or negedge rst)
78
if(~rst)outdata=0;
else
begin
if(pc_wrt_s2)
begin
outdata=indata;
$display("At this posedge contents of pc are %h",outdata);
end
end
endmodule
//************************************************************
module signextender(instr7_4,instr3_0,sign_ext8);
input [3:0] instr7_4,instr3_0;
output [15:0] sign_ext8;
reg [15:0] sign_ext8;
wire [7:0] A,B;
wire [7:0] in;
assign in={instr7_4,instr3_0};
assign A=8'b11111111;
assign B=8'b00000000;
always @ (in)
begin
if (in[7]==0)//use the msb to determine extension bits
sign_ext8={B,in};
else
sign_ext8={A,in};
end
endmodule
//************************************************************
module offset(sign_ext8,dataout,clk);
input [15:0] sign_ext8;
input clk;
output [15:0] dataout;
reg [15:0] dataout;
always @ (posedge clk)
begin
dataout=sign_ext8;
$display("At this posedge register B=%h",dataout);
end
endmodule
//************************************************************
module aluout(datain,dataout,clk);
input [15:0] datain;
input clk;
79
output [15:0] dataout;
reg [15:0] dataout;
always @ (posedge clk)
begin
dataout=datain;
$display("At this posedge of clock register aluout is %h",dataout);
end
endmodule
module opa(datain,dataout,clk);
input [15:0] datain;
input clk;
output [15:0] dataout;
reg [15:0] dataout;
always @ (posedge clk)
begin
dataout=datain;
$display("At this posedge register B=%h",dataout);
end
endmodule
//************************************************************
module opb(datain,dataout,clk);
input [15:0] datain;
input clk;
output [15:0] dataout;
reg [15:0] dataout;
//************************************************************
module mux2_to_1(in0,in1,sel,out);
input [15:0] in0,in1;
input sel;
output [15:0] out;
reg [15:0] out;
always @(sel or in0 or in1)
begin
case(sel)
1'b0: out=in0;
1'b1: out=in1;
endcase
80
end
endmodule
//************************************************************
module mux4_to_1(in0,in1,in2,in3,sel,out);
input [15:0] in0,in1,in2,in3;
input [1:0] sel;
output [15:0] out;
reg [15:0] out;
always @(sel or in0 or in1 or in2 or in3)
begin
case(sel)
2'b00: out=in0;
2'b01: out=in1;
2'b10: out=in2;
2'b11: out=in3;
endcase
end
endmodule
//************************************************************
module mux4b_2_to_1(in0,in1,sel,out);
input [3:0] in0,in1;
input sel;
output [3:0] out;
reg [3:0] out;
always @(sel or in0 or in1)
begin
case(sel)
1'b0: out=in0;
1'b1: out=in1;
endcase
end
endmodule
//************************************************************
module mdr(memdatain,memdataout,clk);
input [15:0] memdatain;
input clk;
output [15:0] memdataout;
reg [15:0]memdataout;
always @ (posedge clk)
memdataout=memdatain;
endmodule
//************************************************************
81
Bibliography
82