Project: memlab2

Contents

Verilog Files

memlab2.v
divide_by_10.v
divide_by_50.v
hex_7seg.v
clock_divider.v
ramtest.v
single_port_ram.v

Quartus Files

fit.summary
tan.summary

Verilog Files

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

Quartus Compilation Summary

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