memlab2.v
module memlab2(
// Clock Input (50 MHz)
input CLOCK_50,
// Push Buttons
input [3:0] KEY,
// DPDT Switches
input [17:0] SW,
// 7-SEG Displays
output [6:0] HEX0, HEX1, HEX2, HEX3, HEX4, HEX5, HEX6, HEX7,
// LEDs
output [8:0] LEDG, // LED Green[8:0]
output [17:0] LEDR // LED Red[17:0]
);
// Connect dip switches to red LEDs
assign LEDR[17:0] = SW[17:0];
// turn off green LEDs
assign LEDG[8:3] = 0;
// define reset
wire RST;
assign RST = KEY[0];
// clock definition
wire [6:0] myclock;
wire clk;
clock_divider cdiv(CLOCK_50,RST,myclock);
assign clk = SW[17]? ~KEY[3]: myclock[0];
// instantiate and connect memory
wire we;
wire [5:0] pc, addr;
wire [7:0] q, qa, inst;
wire [1:0] state;
assign LEDG[0] = state==2'h1;
assign LEDG[1] = state==2'h2;
assign LEDG[2] = state==2'h3;
ramtest ut(
.clk(clk), .reset_n(RST),
.addr(addr), .we(we),
.q(q), .qa(qa), .pc(pc),
.inst(inst), .present(state)
);
// map to 7-segment displays
hex_7seg dsp0(inst[3:0],HEX0);
hex_7seg dsp1(inst[7:4],HEX1);
hex_7seg dsp2(qa[3:0],HEX2);
hex_7seg dsp3(qa[7:4],HEX3);
hex_7seg dsp4(q[3:0],HEX4);
hex_7seg dsp5(q[7:4],HEX5);
hex_7seg dsp6(addr[3:0],HEX6);
hex_7seg dsp7({2'b00,addr[5:4]},HEX7);
localparam blank = ~7'h00;
endmodule
divide_by_10.v
module divide_by_10(Q,CLK,RST);
input CLK, RST;
output Q;
reg Q;
reg [2:0] count;
always @ (posedge CLK or negedge RST)
begin
if (~RST)
begin
Q <= 1'b0;
count <= 3'b000;
end
else if (count < 4)
begin
count <= count+1'b1;
end
else
begin
count <= 3'b000;
Q <= ~Q;
end
end
endmodule
divide_by_50.v
module divide_by_50(Q,CLK,RST);
input CLK, RST;
output Q;
reg Q;
reg [4:0] count;
always @ (posedge CLK or negedge RST)
begin
if (~RST)
begin
Q <= 1'b0;
count <= 5'b00000;
end
else if (count < 24)
begin
count <= count+1'b1;
end
else
begin
count <= 5'b00000;
Q <= ~Q;
end
end
endmodule
hex_7seg.v
module hex_7seg(
input [3:0] hex_digit,
output reg [6:0] seg
);
// seg = {g,f,e,d,c,b,a};
// 0 is on and 1 is off
always @ (hex_digit)
case (hex_digit)
4'h0: seg = ~7'h3F;
4'h1: seg = ~7'h06; // ---a----
4'h2: seg = ~7'h5B; // | |
4'h3: seg = ~7'h4F; // f b
4'h4: seg = ~7'h66; // | |
4'h5: seg = ~7'h6D; // ---g----
4'h6: seg = ~7'h7D; // | |
4'h7: seg = ~7'h07; // e c
4'h8: seg = ~7'h7F; // | |
4'h9: seg = ~7'h67; // ---d----
4'ha: seg = ~7'h77;
4'hb: seg = ~7'h7C;
4'hc: seg = ~7'h39;
4'hd: seg = ~7'h5E;
4'he: seg = ~7'h79;
4'hf: seg = ~7'h71;
endcase
endmodule
clock_divider.v
module clock_divider(CLK,RST,clock);
input CLK,RST;
output [6:0] clock;
wire clk_1Mhz,clk_100Khz,clk_10Khz,clk_1Khz,clk_100hz,clk_10hz,clk_1hz;
assign clock = {clk_1Mhz,clk_100Khz,clk_10Khz,clk_1Khz,clk_100hz,clk_10hz,clk_1hz};
divide_by_50 d6(clk_1Mhz,CLK,RST);
divide_by_10 d5(clk_100Khz,clk_1Mhz,RST);
divide_by_10 d4(clk_10Khz,clk_100Khz,RST);
divide_by_10 d3(clk_1Khz,clk_10Khz,RST);
divide_by_10 d2(clk_100hz,clk_1Khz,RST);
divide_by_10 d1(clk_10hz,clk_100hz,RST);
divide_by_10 d0(clk_1hz,clk_10hz,RST);
endmodule
ramtest.v
module ramtest
#(parameter DATA_WIDTH=8, parameter ADDR_WIDTH=6)
(
input clk, reset_n,
output [(ADDR_WIDTH-1):0] addr,
output we,
output [(DATA_WIDTH-1):0] q, qa,
output reg [ADDR_WIDTH-1:0] pc,
output [(DATA_WIDTH-1):0] inst,
output [1:0] present
);
defparam dev1.DATA_WIDTH = DATA_WIDTH, dev1.ADDR_WIDTH=ADDR_WIDTH;
single_port_ram dev1
(
.data(qa),
.addr(addr),
.we(we),
.clk(clk),
.q(q)
);
reg [1:0] state;
localparam HALT = 2'h3, IF = 2'h1, EX=2'h2;
assign present = state;
wire [ADDR_WIDTH-1:0] nextpc = pc + 1'b1;
assign addr = state==EX? q[ADDR_WIDTH-1:0]: nextpc;
assign we = state==EX? inst[6]: 1'b0;
// define latches
assign qa = state==IF? q: qa;
assign inst = state==EX? q: inst;
always @(posedge clk or negedge reset_n)
begin
if (!reset_n)
begin
pc <= 6'h3F;
state = IF;
end
else
case (state)
IF:
begin
pc <= nextpc;
state <= EX;
end
EX:
begin
if (inst==0) state <= HALT;
else state <= IF;
end
HALT:
begin
pc <= 6'h3F;
state <= HALT;
end
default:
state <= HALT;
endcase
end
endmodule
single_port_ram.v
// Quartus II Verilog Template
// Single port RAM with single read/write address
module single_port_ram
#(parameter DATA_WIDTH=16, parameter ADDR_WIDTH=7)
(
input [(DATA_WIDTH-1):0] data,
input [(ADDR_WIDTH-1):0] addr,
input we, clk,
output [(DATA_WIDTH-1):0] q
);
// Declare the RAM variable
reg [DATA_WIDTH-1:0] ram[0:2**ADDR_WIDTH-1];
// Initialize the RAM with $readmemb. Put the memory contents
// in the file single_port_rom_init.txt. Without this file,
// this design will not compile.
// See Verilog LRM 1364-2001 Section 17.2.8 for details on the
// format of this file.
initial
begin
$readmemh("ram_init.txt", ram);
end
// Variable to hold the registered read address
reg [ADDR_WIDTH-1:0] addr_reg;
always @ (posedge clk)
begin
// Write
if (we)
ram[addr] <= data;
addr_reg <= addr;
end
// Continuous assignment implies read returns NEW data.
// This is the natural behavior of the TriMatrix memory
// blocks in Single Port mode.
assign q = ram[addr_reg];
endmodule
fit.summary
Fitter Status : Successful - Tue Nov 01 20:33:31 2011
Quartus II Version : 9.0 Build 235 06/17/2009 SP 2 SJ Web Edition
Revision Name : memlab2
Top-level Entity Name : memlab2
Family : Cyclone II
Device : EP2C35F672C6
Timing Models : Final
Total logic elements : 122 / 33,216 ( < 1 % )
Total combinational functions : 122 / 33,216 ( < 1 % )
Dedicated logic registers : 39 / 33,216 ( < 1 % )
Total registers : 39
Total pins : 106 / 475 ( 22 % )
Total virtual pins : 0
Total memory bits : 512 / 483,840 ( < 1 % )
Embedded Multiplier 9-bit elements : 0 / 70 ( 0 % )
Total PLLs : 0 / 4 ( 0 % )
tan.summary-------------------------------------------------------------------------------------- Timing Analyzer Summary -------------------------------------------------------------------------------------- Type : Worst-case tco Slack : N/A Required Time : None Actual Time : 26.943 ns From : ramtest:ut|single_port_ram:dev1|altsyncram:ram_rtl_0|altsyncram_tnb1:auto_generated|ram_block1a0~porta_address_reg5 To : HEX7[5] From Clock : CLOCK_50 To Clock : -- Failed Paths : 0 Type : Worst-case tpd Slack : N/A Required Time : None Actual Time : 9.839 ns From : SW[14] To : LEDR[14] From Clock : -- To Clock : -- Failed Paths : 0 Type : Clock Setup: 'SW[17]' Slack : N/A Required Time : None Actual Time : 95.88 MHz ( period = 10.430 ns ) From : ramtest:ut|inst[6] To : ramtest:ut|state.IF From Clock : SW[17] To Clock : SW[17] Failed Paths : 0 Type : Clock Setup: 'KEY[3]' Slack : N/A Required Time : None Actual Time : 95.88 MHz ( period = 10.430 ns ) From : ramtest:ut|inst[6] To : ramtest:ut|state.IF From Clock : KEY[3] To Clock : KEY[3] Failed Paths : 0 Type : Clock Setup: 'CLOCK_50' Slack : N/A Required Time : None Actual Time : 95.88 MHz ( period = 10.430 ns ) From : ramtest:ut|inst[6] To : ramtest:ut|state.IF From Clock : CLOCK_50 To Clock : CLOCK_50 Failed Paths : 0 Type : Clock Hold: 'CLOCK_50' Slack : Not operational: Clock Skew > Data Delay Required Time : None Actual Time : N/A From : clock_divider:cdiv|divide_by_10:d5|count[2] To : clock_divider:cdiv|divide_by_10:d5|Q From Clock : CLOCK_50 To Clock : CLOCK_50 Failed Paths : 1 Type : Total number of failed paths Slack : Required Time : Actual Time : From : To : From Clock : To Clock : Failed Paths : 1 --------------------------------------------------------------------------------------
Maintained by John Loomis, last updated Tue Nov 01 20:35:58 2011