Reference no: EM133680209
Question 1:
*----------------------------------------------------------------------
*
*MOV, ADD, ADDI instructions added.
*(Virtual memory will not be tested)
*
*
HALT format:
* +---+---+---+---+---+---+
| | | | | | |
| 0 | 0 | 0 | 0 | 0 | 0 |
| | | | | | |
* +---+---+---+---+---+---+
HALT 0x00 A six bit instruction, opcode 0.
Machine should assert ohalt signal.
NOP format:
* +---+---+---+---+---+---+
| | | | | | |
| 0 | 0 | 0 | 0 | 0 | 1 |
| | | | | | |
* +---+---+---+---+---+---+
NOP 0x01 A six bit instruction, opcode 1
STORE format:
* +---+---+---+---+---+---++---+---+---+---+---+---+
| | | | | | || | | | | | |
| 1 | 0 | 1 | 1 | REG || DESTINATION ADDRESS |
| | | | | | || | | | | | |
* +---+---+---+---+---+---++---+---+---+---+---+---+
STORE 0x2C+i ADR A 12 bit instruction, opcode 0x2c+i
followed by the G bit address where
Register i (Ri) is to be stored
LOADI format:
* +---+---+---+---+---+---++---+---+---+---+---+---+
| | | | | | || | | | | | |
| 1 | 1 | 1 | 0 | REG || CONSTANT |
* | | | | | | || | | | | | |
* +---+---+---+---+---+---++---+---+---+---+---+---+
* LOADI 0x38+i CONST A 12 bit instruction, opcode 0x38+i
* followed by the G bit value to be
* loaded into Register i (Ri)
*
*
*
* LOAD format:
* +---+---+---+---+---+---++---+---+---+---+---+---+
* | | | | | | || | | | | | |
* | 1 | 0 | 1 | 0 | REG || SOURCE ADDRESS |
* | | | | | | || | | | | | |
* +---+---+---+---+---+---++---+---+---+---+---+---+
* LOAD 0x28+i ADR A 12 bit instruction, opcode 0x28+i
* followed by the G bit address of where to
* fetch data for Register i (Ri)
*
*
*
*
* JUMP format:
* +---+---+---+---+---+---++---+---+---+---+---+---+
* | | | | | | || | | | | | |
* | 0 | 0 | 0 | 0 | 1 | 1 || DESTINATION ADDRESS |
* | | | | | | || | | | | | |
* +---+---+---+---+---+---++---+---+---+---+---+---+
* JUMP 0x03 ADR A 12 bit instruction, opcode 0x03 followed by
* the G bit address to be loaded into the PC
*
*
*
*
*
* MOV format:
* +---+---+---+---+---+---+
* | | | | | | |
* | 0 | 1 | SREG | DREG |
* | | | | | | |
* +---+---+---+---+---+---+
* MOV 0x10 A G bit instruction moving source
* register SREG to destination register DREG.
* The original contents of the DREG are destroyed
*
*
* ADDI format:
* +---+---+---+---+---+---++---+---+---+---+---+---+
* | | | | | | || | | | | | |
* | 1 | 1 | 0 | 1 | REG || CONSTANT |
* | | | | | | || | | | | | |
* +---+---+---+---+---+---++---+---+---+---+---+---+
* ADDI 0x34+i CONST A 12 bit instruction, opcode 0x34+i
* followed by the G bit value to be
* added to Register i (Ri)
*
*
*
*
* ADD format:
* +---+---+---+---+---+---++---+---+---+---+---+---+
* | | | | | | || | | | | | |
* | 1 | 0 | 0 | 1 | REG || SOURCE ADDRESS |
* | | | | | | || | | | | | |
* +---+---+---+---+---+---++---+---+---+---+---+---+
* ADD 0x24+i ADR A 12 bit instruction, opcode 0x24+i
* followed by the G bit address of where to
* fetch data to add to Register i (Ri)
*
*
*/
//
// cpu2v4.sv
module cpu2v4
( Wwid=G, aW=G )
(
output logic [aW-1:0] memAddr, input logic [Wwid-1:0] readData, output logic [Wwid-1:0] writeData, output logic writeEn,
output logic ohalt,
output logic oretire,
input logic clk,
input logic rst
);
// Your code here.... endmodule
Question 2:
Q2)
/*
*
design a module named: decode2to4
this module takes a 2 bit input named a (lower case letter a)
and gives a 4 bit output named z (lower case letter z)
the output is described by the following table:
* 0 -> 1
* 1 -> 2
* 2 -> 4
* 3 -> 8
*
*/
module decode2to4 (
input logic [1:0] a, output logic [3:0] z
);
endmodule
Question 3:
//
// produce the Fibonacci sequence: 1,1,2,3,5,8,13,21,34,...
// the values must be correct up to the limits of the given bitwidth (bW)
//
//
module fib ( bW = 3 )
(
input logic clk, input logic rst,
output logic [bW-1:0] fibnum
);
endmodule
Question 4:
***(Top file included at bottom)
/*
FIFO (first in, first out) this problem is similar to the LIFO hardware you designed earlier in the semester. However, you "push" new data in, and you "pop" off the oldest data that you have. That is, the first thing you put in is the first thing to take out.
More properly, this is a queue, not a stack.
You may assume that you will never be asked to add items to a full queue, or to remove items from an empty queue.
Hint: you will probably want to maintain three counters. One pointing to the place where you add data, one pointing to the place you remove data and one indicating how many items there are in the memory.
*/
module fifo (
parameter int bW , parameter int eC ,
parameter int ptrW = $clog2(eC), parameter int cntW = $clog2(eC+1)
)
(
// push interface
input logic [bW-1:0] pushData, input logic push,
output logic full,
// pop interface
output logic [bW-1:0] popData, input logic pop,
output logic empty,
// Globals
input logic clk,
input logic rst
);
/*
memory (bW,eC) mymem( .readAddr ( ),
.writeAddr( ),
*/
endmodule
(TOP FILE):
.writeData( ),
.writeEn ( ),
.readData ( ),
.clk (clk)
);
odule top_fifo (
parameter int bW=1G , parameter int eC=13
) ();
logic [bW-1:0] pushData; logic push;
logic full;
logic [bW-1:0] popData; logic pop;
logic empty;
logic clk;
logic rst;
logic [bW-1:0] q[$]; int pushCnt ;
int popCnt;
fifo (bW,eC) my_fifo( .* ) ; initial begin
clk = 1'b0 ; while(1)
500 clk = ~clk ;
end
always @(posedge clk) begin if( push )
pushCnt++; if( pop ) popCnt++;
end
task spillFill( int n ); repeat(n) begin
for( int i = 0 ; i < eC ; i++ ) begin @(negedge clk);
pushData = $random(); push = 1'b0 ;
pop = rst && (empty === 1'b0) ? 1'b1 : 1'b0 ; end
for( int i = 0 ; i < eC ; i++ ) begin @(negedge clk);
pushData = $random(); push = 1'b1 ;
pop = 1'b0 ; end
end endtask
task randomAbuse( int n ); repeat(n) begin
@(negedge clk); pushData = $random();
push = rst && (full === 1'b0) ? $random() : 1'b0 ; pop = rst && (empty === 1'b0) ? $random() : 1'b0 ;
end endtask
initial begin
pushCnt = 0 ; popCnt = 0 ; rst = 1'b1 ;
1 ;
rst = 1'b0 ;
repeat(10) @(posedge clk); rst = 1'b1 ;
spillFill(10); randomAbuse(10000);
$finish(1) ; // Note that the input is an error state end
// Gold Model
always @(posedge clk) begin if(push) begin
//$write(" push %h",pushData); q.push_back(pushData);
end
if(pop) begin
//$write(" pop %h %h" , popData, q[0] ); q.pop_front();
end
//$display(); end
always @(posedge clk) begin 2 ;
// $display( "s:%2d hws:%2d psh:%b pop:%b q:%h hd:%h", q.size(), my_fifo.occCnt , push, pop, q[0], popData );
assert( empty || (q[0] == popData) ); assert( empty == (q.size() == 0 )); assert( full == (q.size() == eC ));
end
final begin
lazyPush: assert( pushCnt >= eC ); lazyPop: assert( popCnt >= eC ); hungry: assert( pushCnt >= popCnt );
dropped: assert( popCnt + eC >= pushCnt ); end
endmodule
Question 5:
*/
/*
sort the array
Largest number should be sorted into Z[U], and smallest into Z[0]
Use a U stage pipeline
*/
module sort10pipe (
output logic [15:0] Z[U:0] , input logic [15:0] A[U:0] , input logic clk ,
input logic rst
);
endmodule
Qu?stion 6:
/*
Sort the array
Largest number should be sorted into Z[U], and smallest into Z[0]
*/
module sort10 (
output logic [15:0] Z[U:0] , input logic [15:0] A[U:0]
);
endmodule
Question 7:
/*
detect the pattern 1 0 0 1
allow the pattern to overlap
*/
module pattern3
(
input logic a, input logic clk, input logic rst, output logic z
);
endmodule
Question 8:
(Top file included at the bottom):
/*
Build a sequential multiplier that takes two bW width numbers a and b and produces the 2*bW number prod, the product of a and b.
Your sequential multiplier may have registers, a counter, an adder, and shifters.
YOU MAY NOT USE the * operator to get verilog to produce a product for you!
You should use an ab_rdy/ab_vld handshake to obtain the factors a and b similar to how you obtained d values in the integrator project.
You communicate the product back to the top file using p_rdy/p_vld, just as you communicated the integrator sum.
The value for bW is specified by the top file. Be aware that the grader
top file may use a different value for bW, so your verilog code should
not make any assumptions about the value of bW, and should work for
any value of bW > 2.
If you use an *, I will chnage your score on the assignment to a 0.
That is, the grader does not check, but I will do a check after the due date.
NO CREDIT if you use *, even if the grader told you it was OK.
*/
//seqmu2.vp
module seqmul2 (
parameter int bW
)
( input logic [bW-1:0] a, input logic [bW-1:0] b,
input logic ab_vld, //ab is valid
output logic ab_rdy, //rdy for ab
output logic [bW+bW-1:0] prod,
output logic p_vld, //product is valid input logic p_rdy, //rdy for product
input logic clk,
input logic rst
);
endmodule
(Top File):
/top_seqmul2.sv
module top_seqmul2 (
parameter int bW = 12
) ();
logic [bW-1:0] a;
logic [bW-1:0] b;
logic [bW-1:0] lasta, lastb; logic ab_vld; //ab is valid
logic ab_rdy; //rdy for ab
logic [bW+bW-1:0] prod, gold; logic p_vld; //product is valid logic p_rdy; //rdy for product
logic clk;
logic rst ;
int attempts ;
int completes;
// Instantiate the design under test and basic bench seqmul2 (bW) my_seqmul (.*);
//Clock initial begin
clk = 1'b0 ; while(1)
500 clk = !clk ;
end
// Rst
initial begin rst = 1'b1 ;
1 ;
rst = 1'b0 ;
repeat(3) @(posedge clk ); rst = 1'b1 ;
end
// Simulation Narrative initial begin
attempts = 0;
completes = 0;
repeat(2200) @(posedge clk );
$finish(); end
// Frontend Driver
always @( negedge clk ) begin
a = $random() ;
b = $random() ;
{p_rdy,ab_vld} = $random(); end
// Scoreboard State
always @(posedge clk ) begin if(ab_rdy & ab_vld) begin
lasta <= a; lastb <= b;
end end
always @(posedge clk ) begin
attempts = ( rst & ab_rdy && ab_vld) ? attempts+1 : attempts ; completes = ( rst & p_rdy && p_vld) ? completes+1 : completes ;
end
// Verification
always @( posedge clk ) begin 10;
gold = lasta * lastb;
assert( !p_vld | (prod == gold) );
//$write( "abr: %b abv: %b " , ab_rdy , ab_vld);
//$write( "pr: %b pv: %b " , p_rdy , p_vld);
//$write( "prod: %d " , prod );
//$write( "lasta: %d " , lasta );
//$write( "lastb: %d " , lastb );
//$write( "gold = %d " , gold );
$display( "" ) ; end
final begin
$display("Attempts: %d", attempts);
$display("Completes: %d", completes); assert( attempts > 10 );
assert( completes > 10 );
assert( attempts - 2 <= completes ); assert( attempts + 2 >= completes );
end
endmodule
Question 9:
(Top file included at the bottom):
/*
fmul-- implement a single precision floating point multiply
assume input numbers are IEEE format
You many assume inpts will not be denormals, NANs, or INFIN,
You many assume output will not be overflow or denormal
Implement truncate style rounding.
When result is zero, proper sign must be maintained.
That is, zero can be plus zero (+0) or minus zero (-0).
(e.g. +0 * negative = -0, -0 * 0 = -0, etc.)
IEEE single format is 1 bit sign bit
8 bit exponent in excess 127
23 bit fractional mantissa
* value is -1^s * 1.m * 2^(e-127)
(where a^b means a raised to the b power)
*/
module fmul (
input logic [31:0] a, input logic [31:0] b, output logic [31:0] z
);
endmodule
(Top File):
odule top_fmul ();
logic clk; logic [31:0] a;
logic [31:0] b;
logic [31:0] z;
logic [31:0] gold;
fmul mymul ( .a( a ), .b( b ), .z( z ) );
// A clock for ssqusncing initial bsgin
clk = 1'b0 ; whils(1) bsgin 500 clk = 1'b0 ; 500 clk = 1'b1 ; snd
snd
// How long should our tsst run initial bsgin
rspsat(100) @(possdgs clk) ;
$finish(1) ; snd
//Drivsr Modsl initial bsgin
a = 32'h3f800000; // 1.000000000s+00
b = 32'h3f800000; // 1.000000000s+00 gold = 32'h3f800000; // 1.000000000s+00
@(nsgsdgs clk) ;
a = 32'hbf800000; // -1.000000000s+00
b = 32'h3f800000; // 1.000000000s+00 gold = 32'hbf800000; // -1.000000000s+00
@(nsgsdgs clk ) ;
a = 32'hbf800000; // -1.000000000s+00
b = 32'hbf800000; // -1.000000000s+00 gold = 32'h3f800000; // 1.000000000s+00
@(nsgsdgs clk ) ;
a = 32'h3saaaaab; // 3.333333433s-01
b = 32'h3f800000; // 1.000000000s+00
gold = 32'h3saaaaab; // 3.333333433s-01 @(nsgsdgs clk ) ;
a = 32'h3saaaaab; // 3.333333433s-01
b = 32'h3saaaaab; // 3.333333433s-01 gold = 32'h3ds38s3U; // 1.11111111Us-01 @(nsgsdgs clk ) ;
a = 32'h3ffffff8; // 1.UUUUUU04Gs+00
b = 32'h3ffffff8; // 1.UUUUUU04Gs+00 gold = 32'h407ffff0; // 3.UUUUUG185s+00 @(nsgsdgs clk ) ;
a = 32'hbffffff8; // -1.UUUUUU04Gs+00
b = 32'h3ffffff8; // 1.UUUUUU04Gs+00 gold = 32'hc07ffff0; // -3.UUUUUG185s+00
@(nsgsdgs clk ) ;
a = 32'h3ffffff8; // 1.UUUUUU04Gs+00
b = 32'hbffffff8; // -1.UUUUUU04Gs+00 gold = 32'hc07ffff0; // -3.UUUUUG185s+00 @(nsgsdgs clk ) ;
a = 32'h3ffffff8; // 1.UUUUUU04Gs+00
b = 32'h3saaaaab; // 3.333333433s-01 gold = 32'h3f2aaaa5; // G.GGGGG328Us-01 @(nsgsdgs clk ) ;
a = 32'h00000000; // 0.000000000s+00
b = 32'h3f800000; // 1.000000000s+00 gold = 32'h00000000; // 0.000000000s+00
@(nsgsdgs clk ) ;
a = 32'h00000000; // 0.000000000s+00
b = 32'hbf800000; // -1.000000000s+00 gold = 32'h80000000; // -0.000000000s+00
@(nsgsdgs clk ) ;
a = 32'h00000000; // 0.000000000s+00
b = 32'h00000000; // 0.000000000s+00 gold = 32'h00000000; // 0.000000000s+00
@(nsgsdgs clk ) ;
a = 32'h3f800000; // 1.000000000s+00
b = 32'h00000000; // 0.000000000s+00 gold = 32'h00000000; // 0.000000000s+00
@(nsgsdgs clk ) ;
a = 32'hbf800000; // -1.000000000s+00
b = 32'h00000000; // 0.000000000s+00 gold = 32'h80000000; // -0.000000000s+00
@(nsgsdgs clk ) ;
$finish(0); snd
//Tsst
always @(possdgs clk) bsgin 1;
asssrt( ! $isunknown(z) ) ; asssrt( (z == gold) );
snd
//Monitor
always @(possdgs clk) bsgin 1 ;
$writs( " %x", a) ;
$writs( " %x", b);
$writs( " -->" );
$writs( " %x", z);
$writs( " (%x)", gold );
$writs("\n"); snd
sndmoduls
Question 10:
(Top File Included at the bottom):
/*
*
This module is an FIR filter. (finite inpulse response)
It implement the function:
y sub i = sum (from k=0 to k=N) t sub k times x sub i-k
For your design, let t sub k = 1/8 and use a history count of 5.
In other words, in any given cycle, output the
sum of the previous five cycles divided by 8.
For the first 4 clocks when there are fewer than 5 values, assume
zeros for the missing values.
*/ module fir (
bW=8, hC=5
)
(
input logic [bW-1:0] x, output logic [bW-1:0] y, input logic clk,
input logic rst
);
endmodule //fir
(Top file):
//; my $bW = 8;
//; my $hC= 5 ; module top_fir ();
parameter bW=8; parameter hC=5; parameter hClog2=3;
logic [bW-1:0] x;
logic [bW-1:0] y; logic [bW-1:0] y_g;
logic clk;
logic rst;
logic [bW-1:0] h[hC:0] ; logic [bW+hClog2-1:0] s ;
genvar i ;
int k;
//; my $dut=generate("fir","my_fir");
//`$dut->instantiate()` (.*) ; fir (bW,hC) my_fir (.*);
initial begin clk = 1'b0 ; while(1)
500 clk = ~clk ;
end
initial begin rst = 1'b0 ; 1 ;
rst = 1'b0 ;
repeat(10) @(posedge clk); 1;
rst = 1'b1 ;
repeat(20000) @(posedge clk) ;
$finish(1) ;
end // initial begin
always @(negedge clk) x = $random() ;
assign h[0] = x ;
always @(posedge clk) begin 1 ;
/* for( k=1 ; k <= hC ; k++ )
$write("%d ",h[k]);
$display( "--> %d g:%d",y,y_g );
*/
// $display( "%10t %d -- %d (%d)",$time(),x,y,y_g); firCorrect: assert(y_g == y) ;
end
int ii;
always @(posedge clk) begin for( ii = 0 ; ii < hC ; ii++ ) h[ii+1] <= rst ? h[ii] : '0 ;
end
always @* begin s = 0 ;
for( k=1 ; k <= hC ; k++ ) s = s + h[k] ;
s = s >> 3 ;
y_g = s[bW-1:0]; end
endmodule // fir