首页 > 代码库 > omsp430ikmcu verilog代码

omsp430ikmcu verilog代码

《open msp430应用笔记》中对应的verilog代码

mcu core顶层:omsp430.v

技术分享
//----------------------------------------------------------------------------
//
// *File Name: openMSP430.v
//
// *Module Description:
//                       openMSP430 Top level file
//
// *Author(s):
//              - Olivier Girard,    olgirard@gmail.com
//
//---------------------------------------------------------------------------
//
// $LastChangedBy: wuzhangquan wuzhangquan@foxmail.com $
// $LastChangedDate: 2017-6-16$
//
//----------------------------------------------------------------------------

`include "timescale.v"
`include "openMSP430_defines.v"

module  omsp430(
    output [`DMEM_MSB:0] dmem_addr,    // Data Memory address
    output               dmem_cen,     // Data Memory chip enable (low active)
    output        [15:0] dmem_din,     // Data Memory data input
    output         [1:0] dmem_wen,     // Data Memory write enable (low active)
    input         [15:0] dmem_dout,    // Data Memory data output

    output [`PMEM_MSB:0] pmem_addr,    // Program Memory address
    output               pmem_cen,     // Program Memory chip enable (low active)
    output        [15:0] pmem_din,     // Program Memory data input (optional)
    output         [1:0] pmem_wen,     // Program Memory write enable (low active) (optional)
    input         [15:0] pmem_dout,    // Program Memory data output

    output         [7:0] per_addr,     // Peripheral address
    output        [15:0] per_din,      // Peripheral data input
    output         [1:0] per_wen,      // Peripheral write enable (high active)
    output               per_en,       // Peripheral enable (high active)
    input         [15:0] per_dout,     // Peripheral data output

    output  [15:0]       dma_dout,
    input   [15:0]       dma_addr,
    input   [15:0]       dma_din,
    input                dma_en,
    input   [1:0]        dma_wr,
    input                cpu_halt,

    output        [13:0] irq_acc,      // Interrupt request accepted (one-hot signal)
    input            [13:0] irq,          // Maskable interrupts
    
    input                mclk,         // Main system clock
    input                puc           // Main system reset
   );

//=============================================================================
// 1)  INTERNAL WIRES/REGISTERS/PARAMETERS DECLARATION
//=============================================================================

wire          [7:0] inst_ad;
wire          [7:0] inst_as;
wire         [11:0] inst_alu;
wire                inst_bw;
wire         [15:0] inst_dest;
wire         [15:0] inst_dext;
wire         [15:0] inst_sext;
wire          [7:0] inst_so;
wire         [15:0] inst_src;
wire          [2:0] inst_type;
wire          [3:0] e_state;
wire                exec_done;

wire         [15:0] eu_mab;
wire         [15:0] eu_mdb_in;
wire         [15:0] eu_mdb_out;
wire          [1:0] eu_mb_wr;
wire         [15:0] fe_mab;
wire         [15:0] fe_mdb_in;

wire         [15:0] pc_sw;
wire          [7:0] inst_jmp;
wire         [15:0] pc;
wire         [15:0] pc_nxt;

wire         [15:0] dbg_mem_addr;
wire         [15:0] dbg_mem_dout;
wire         [15:0] dbg_mem_din;
wire         [15:0] dbg_reg_din;
wire          [1:0] dbg_mem_wr;

wire         [15:0] per_dout_or;
//wire         [15:0] per_dout_sfr;
//wire         [15:0] per_dout_wdog;
//wire         [15:0] per_dout_clk;

// wuzhangquan adding
wire                nmi_evt = 1b0;
wire                wdt_irq = 1b0;
   
//=============================================================================
// 3)  FRONTEND (<=> FETCH & DECODE)
//=============================================================================

omsp_frontend frontend_0 (

// OUTPUTs
    .dbg_halt_st  (dbg_halt_st),   // Halt/Run status from CPU
    .decode_noirq (decode_noirq),  // Frontend decode instruction
    .e_state      (e_state),       // Execution state
    .exec_done    (exec_done),     // Execution completed
    .inst_ad      (inst_ad),       // Decoded Inst: destination addressing mode
    .inst_as      (inst_as),       // Decoded Inst: source addressing mode
    .inst_alu     (inst_alu),      // ALU control signals
    .inst_bw      (inst_bw),       // Decoded Inst: byte width
    .inst_dest    (inst_dest),     // Decoded Inst: destination (one hot)
    .inst_dext    (inst_dext),     // Decoded Inst: destination extended instruction word
    .inst_irq_rst (inst_irq_rst),  // Decoded Inst: Reset interrupt
    .inst_jmp     (inst_jmp),      // Decoded Inst: Conditional jump
    .inst_sext    (inst_sext),     // Decoded Inst: source extended instruction word
    .inst_so      (inst_so),       // Decoded Inst: Single-operand arithmetic
    .inst_src     (inst_src),      // Decoded Inst: source (one hot)
    .inst_type    (inst_type),     // Decoded Instruction type
    .irq_acc      (irq_acc),       // Interrupt request accepted
    .mab          (fe_mab),        // Frontend Memory address bus
    .mb_en        (fe_mb_en),      // Frontend Memory bus enable
    .nmi_acc      (nmi_acc),       // Non-Maskable interrupt request accepted
    .pc           (pc),            // Program counter
    .pc_nxt       (pc_nxt),        // Next PC value (for CALL & IRQ)
                 
// INPUTs
    .cpuoff       (cpuoff),        // Turns off the CPU
    .dbg_halt_cmd (dbg_halt_cmd),  // Halt CPU command
    .dbg_reg_sel  (dbg_mem_addr[3:0]), // Debug selected register for rd/wr access
    .fe_pmem_wait (fe_pmem_wait),  // Frontend wait for Instruction fetch
    .gie          (gie),           // General interrupt enable
    .irq          (irq),           // Maskable interrupts
    .mclk         (mclk),          // Main system clock
    .mdb_in       (fe_mdb_in),     // Frontend Memory data bus input
    .nmi_evt      (nmi_evt),       // Non-maskable interrupt event
    .pc_sw        (pc_sw),         // Program counter software value
    .pc_sw_wr     (pc_sw_wr),      // Program counter software write
    .puc          (puc),           // Main system reset
    .wdt_irq      (wdt_irq)        // Watchdog-timer interrupt
);


//=============================================================================
// 4)  EXECUTION UNIT
//=============================================================================

omsp_execution_unit execution_unit_0 (

// OUTPUTs
    .cpuoff       (cpuoff),        // Turns off the CPU
    .gie          (gie),           // General interrupt enable    //:wuzhangquan
    .dbg_reg_din  (dbg_reg_din),   // Debug unit CPU register data input
    .mab          (eu_mab),        // Memory address bus
    .mb_en        (eu_mb_en),      // Memory bus enable
    .mb_wr        (eu_mb_wr),      // Memory bus write transfer
    .mdb_out      (eu_mdb_out),    // Memory data bus output
    .oscoff       (oscoff),        // Turns off LFXT1 clock input
    .pc_sw        (pc_sw),         // Program counter software value
    .pc_sw_wr     (pc_sw_wr),      // Program counter software write
    .scg1         (scg1),          // System clock generator 1. Turns off the SMCLK

// INPUTs
//   .cpu_stop     (1‘b0       ),    //Adding by wuzhangquan @2015-02-06
    .dbg_halt_st  (dbg_halt_st),   // Halt/Run status from CPU
    .dbg_mem_dout (dbg_mem_dout),  // Debug unit data output
    .dbg_reg_wr   (dbg_reg_wr),    // Debug unit CPU register write
    .e_state      (e_state),       // Execution state
    .exec_done    (exec_done),     // Execution completed
//    .gie          (gie),           // General interrupt enable    //:wuzhangquan
    .inst_ad      (inst_ad),       // Decoded Inst: destination addressing mode
    .inst_as      (inst_as),       // Decoded Inst: source addressing mode
    .inst_alu     (inst_alu),      // ALU control signals
    .inst_bw      (inst_bw),       // Decoded Inst: byte width
    .inst_dest    (inst_dest),     // Decoded Inst: destination (one hot)
    .inst_dext    (inst_dext),     // Decoded Inst: destination extended instruction word
    .inst_irq_rst (inst_irq_rst),  // Decoded Inst: reset interrupt
    .inst_jmp     (inst_jmp),      // Decoded Inst: Conditional jump
    .inst_sext    (inst_sext),     // Decoded Inst: source extended instruction word
    .inst_so      (inst_so),       // Decoded Inst: Single-operand arithmetic
    .inst_src     (inst_src),      // Decoded Inst: source (one hot)
    .inst_type    (inst_type),     // Decoded Instruction type
    .mclk         (mclk),          // Main system clock
    .mdb_in       (eu_mdb_in),     // Memory data bus input
    .pc           (pc),            // Program counter
    .pc_nxt       (pc_nxt),        // Next PC value (for CALL & IRQ)
    .puc          (puc)            // Main system reset
);


//=============================================================================
// 5)  MEMORY BACKBONE
//=============================================================================

omsp_mem_backbone mem_backbone_0 (

// OUTPUTs
    .dbg_mem_din  (dbg_mem_din),   // Debug unit Memory data input
    .dmem_addr    (dmem_addr),     // Data Memory address
    .dmem_cen     (dmem_cen),      // Data Memory chip enable (low active)
    .dmem_din     (dmem_din),      // Data Memory data input
    .dmem_wen     (dmem_wen),      // Data Memory write enable (low active)
    .eu_mdb_in    (eu_mdb_in),     // Execution Unit Memory data bus input
    .fe_mdb_in    (fe_mdb_in),     // Frontend Memory data bus input
    .fe_pmem_wait (fe_pmem_wait),  // Frontend wait for Instruction fetch
    .per_addr     (per_addr),      // Peripheral address
    .per_din      (per_din),       // Peripheral data input
    .per_wen      (per_wen),       // Peripheral write enable (high active)
    .per_en       (per_en),        // Peripheral enable (high active)
    .pmem_addr    (pmem_addr),     // Program Memory address
    .pmem_cen     (pmem_cen),      // Program Memory chip enable (low active)
    .pmem_din     (pmem_din),      // Program Memory data input (optional)
    .pmem_wen     (pmem_wen),      // Program Memory write enable (low active) (optional)
                 
// INPUTs
    .dbg_halt_st  (dbg_halt_st),   // Halt/Run status from CPU
    .dbg_mem_addr (dbg_mem_addr),  // Debug address for rd/wr access
    .dbg_mem_dout (dbg_mem_dout),  // Debug unit data output
    .dbg_mem_en   (dbg_mem_en),    // Debug unit memory enable
    .dbg_mem_wr   (dbg_mem_wr),    // Debug unit memory write
    .dmem_dout    (dmem_dout),     // Data Memory data output
    .eu_mab       (eu_mab[15:1]),  // Execution Unit Memory address bus
    .eu_mb_en     (eu_mb_en),      // Execution Unit Memory bus enable
    .eu_mb_wr     (eu_mb_wr),      // Execution Unit Memory bus write transfer
    .eu_mdb_out   (eu_mdb_out),    // Execution Unit Memory data bus output
    .fe_mab       (fe_mab[15:1]),  // Frontend Memory address bus
    .fe_mb_en     (fe_mb_en),      // Frontend Memory bus enable
    .mclk         (mclk),          // Main system clock
    .per_dout     (per_dout_or),   // Peripheral data output
    .pmem_dout    (pmem_dout),     // Program Memory data output
    .puc          (puc)            // Main system reset
);

//=============================================================================
// 8)  PERIPHERALS‘ OUTPUT BUS
//=============================================================================

assign  per_dout_or  =  per_dout      ;//|
   
assign dbg_freeze   =  1b0;
assign dbg_halt_cmd =  cpu_halt;
assign dbg_mem_addr =  dma_addr;
assign dbg_mem_dout =  dma_din;
assign dbg_mem_en   =  dma_en;
assign dbg_mem_wr   =  dma_wr;
assign dbg_reg_wr   =  1b0;
assign dbg_reset    =  1b0;

assign  dma_dout    = dbg_mem_din;

endmodule // omsp430mcu
`include "openMSP430_undefines.v"
View Code

 

sys顶层:

技术分享
//----------------------------------------------------------------------------
//
// *File Name: omsp430ik_sys.v
//
// *Module Description:
//                       
//
// *Author(s):
//              - wuzhangquan,   wuzhangquan@foxmail.com
//
//---------------------------------------------------------------------------

`include "openMSP430_defines.v"
module  omsp430ik_sys
    (
        //GPIO
        input       [7:0]   gpio1_din,
        output      [7:0]   gpio1_dout,
        output      [7:0]   gpio1_dir,
        //UART
        output              txd,
        input               rxd,
        
        //clock
        input               mclk,       //mcu main clock
        input               puc         //mcu power up clear

    );

// Data Memory interface
wire [`DMEM_MSB:0]  dmem_addr;
wire                dmem_cen;
wire        [15:0]  dmem_din;
wire         [1:0]  dmem_wen;
wire        [15:0]  dmem_dout;

// Program Memory interface
wire [`PMEM_MSB:0]  pmem_addr;
wire                pmem_cen;
wire        [15:0]  pmem_din;
wire         [1:0]  pmem_wen;
wire        [15:0]  pmem_dout;

// Peripherals interface
wire         [7:0]  per_addr;
wire        [15:0]  per_din;
wire        [15:0]  per_dout;
wire         [1:0]  per_wen;
wire                per_en;

//  dma(Add by wuzhangquan)
wire  [15:0]        dma_dout;
wire  [15:0]        dma_addr = 0;
wire  [15:0]        dma_din  = 0;
wire                dma_en   = 0;
wire  [1 :0]        dma_wen  = 0;
wire                cpu_halt = 0;

// Interrupt
wire  [13:0]        irq_acc;
wire  [13:0]        irq_in;

//gpio_1
wire    [15:0]      per_dout_gpio_1;
wire                irq_port1;
wire                irq_port2 = 1b0;
// uart
wire    [15:0]      per_dout_uart;
wire    [15:0]      per_dout_8bit;


//
// openMSP430 Instance
//----------------------------------
omsp430 omsp430_0 (
    .dmem_addr    (dmem_addr),         // Data Memory address
    .dmem_cen     (dmem_cen),          // Data Memory chip enable (low active)
    .dmem_din     (dmem_din),          // Data Memory data input
    .dmem_wen     (dmem_wen),          // Data Memory write enable (low active)
    .dmem_dout    (dmem_dout),         // Data Memory data output

    .pmem_addr    (pmem_addr),         // Program Memory address
    .pmem_cen     (pmem_cen),          // Program Memory chip enable (low active)
    .pmem_din     (pmem_din),          // Program Memory data input (optional)
    .pmem_wen     (pmem_wen),          // Program Memory write enable (low active) (optional)
    .pmem_dout    (pmem_dout),         // Program Memory data output

    .per_addr     (per_addr),          // Peripheral address
    .per_din      (per_din),           // Peripheral data input
    .per_wen      (per_wen),           // Peripheral write enable (high active)
    .per_en       (per_en),            // Peripheral enable (high active)
    .per_dout     (per_dout),          // Peripheral data output

    .dma_dout     (dma_dout),
    .dma_addr     (dma_addr),
    .dma_din      (dma_din),
    .dma_en       (dma_en),
    .dma_wr       (dma_wen),
    .cpu_halt     (cpu_halt),

    .irq_acc      (irq_acc),           // Interrupt request accepted (one-hot signal)
    .irq          (irq_in),            // Maskable interrupts

    ////////////////////////
    //cock
    ////////////////////////
    .mclk        (mclk),
    .puc         (puc)
);

//
// Program Memory
//----------------------------------

omsp430_pmem #(`PMEM_MSB) pmem_0 (

// OUTPUTs
    .ram_dout    (pmem_dout),          // Program Memory data output

// INPUTs
    .ram_addr    (pmem_addr ),          // Program Memory address
    .ram_cen     (pmem_cen  ),          // Program Memory chip enable (low active)
    .ram_clk     (mclk      ),          // Program Memory clock
    .ram_din     (pmem_din  ),          // Program Memory data input
    .ram_wen     (pmem_wen  )           // Program Memory write enable (low active)
);

//
// Data Memory
//----------------------------------
omsp430_dmem #(`DMEM_MSB) dmem_0 (
// OUTPUTs
    .ram_dout    (dmem_dout   ),          // Data Memory data output

// INPUTs
    .ram_addr    (dmem_addr   ),          // Data Memory address
    .ram_cen     (dmem_cen    ),          // Data Memory chip enable (low active)
    .ram_clk     (mclk        ),          // Data Memory clock
    .ram_din     (dmem_din    ),          // Data Memory data input
    .ram_wen     (dmem_wen    )           // Data Memory write enable (low active)
);

gpio  #(.BASIC_ADDR(16h20)) gpio_1 (

    .gpio_din       (gpio1_din   ),
    .gpio_dout      (gpio1_dout  ),
    .gpio_dir       (gpio1_dir   ),
    .irq_gpio       (irq_port1  ),

    // CPU If
    .per_dout       (per_dout_gpio_1),   // Peripheral data output

    .per_addr       (per_addr),          // Peripheral address
    .per_din        (per_din),           // Peripheral data input
    .per_wen        (per_wen),           // Peripheral write enable (high active)
    .per_en         (per_en),            // Peripheral enable (high active)
    .mclk           (mclk),
    .puc            (puc)
    );



uart  #(.BASIC_ADDR(16h40)) uart_0 (

    .txd            (txd),
    .rxd            (rxd),

    // CPU If
    .per_dout       (per_dout_uart),     // Peripheral data output

    .per_addr       (per_addr),          // Peripheral address
    .per_din        (per_din),           // Peripheral data input
    .per_wen        (per_wen),           // Peripheral write enable (high active)
    .per_en         (per_en),            // Peripheral enable (high active)
    .mclk           (mclk),
    .puc            (puc)
    );

template_periph_8b  #(.BASIC_ADDR(16h90)) temp_8b_0 (

    // CPU If
    .per_dout       (per_dout_8bit),     // Peripheral data output

    .per_addr       (per_addr),          // Peripheral address
    .per_din        (per_din),           // Peripheral data input
    .per_wen        (per_wen),           // Peripheral write enable (high active)
    .per_en         (per_en),            // Peripheral enable (high active)
    .mclk           (mclk),
    .puc            (puc)
    );



//
// Combine peripheral data bus
//----------------------------------

assign per_dout  =  per_dout_gpio_1   |
                    per_dout_uart     |
                    per_dout_8bit;


//
// Map peripheral interrupts
//----------------------------------------

assign irq_in = {
                    1b0,           // Vector 13  (0xFFFA)
                    1b0,           // Vector 12  (0xFFF8)
                    1b0,           // Vector 11  (0xFFF6)
                    1b0,           // Vector 10  (0xFFF4) - Watchdog -
                    1b0,           // Vector  9  (0xFFF2) - irq_ta0 -
                    1b0,           // Vector  8  (0xFFF0) - irq_ta1 -
                    1b0,           // Vector  7  (0xFFEE)
                    1b0,           // Vector  6  (0xFFEC)
                    1b0,           // Vector  5  (0xFFEA)
                    1b0,           // Vector  4  (0xFFE8)
                    irq_port2,      // Vector  3  (0xFFE6) - irq_port2 -
                    irq_port1,      // Vector  2  (0xFFE4) - irq_port1 - 
                    1b0,           // Vector  1  (0xFFE2)
                    1b0};          // Vector  0  (0xFFE0
endmodule
`include "openMSP430_undefines.v"
View Code

 

mcu顶层:

技术分享
`timescale  1ns/1ns
module  omsp430ikmcu
    (

        inout   tri1  [7:0]   P1,
        
        output                txd,
        input                 rxd,

        input                 CLK,
        input                 nRESET
    );

wire  [7:0] gpio1_din;
wire  [7:0] gpio1_dout;
wire  [7:0] gpio1_dir;

//
//  clock and reset module
//-----------------------------
wire    mclk    =   CLK;
wire    puc     =   ~nRESET;


omsp430ik_sys   u_sys
    (
        .gpio1_din    (gpio1_din),
        .gpio1_dout   (gpio1_dout),
        .gpio1_dir    (gpio1_dir),
        
        .txd          (txd),
        .rxd          (rxd),

        .mclk         (mclk   ),
        .puc          (puc    )
    );


// io mux
assign  P1[7]  = gpio1_dir[7]?  gpio1_dout[7]  : 1bz;
assign  P1[6]  = gpio1_dir[6]?  gpio1_dout[6]  : 1bz;
assign  P1[5]  = gpio1_dir[5]?  gpio1_dout[5]  : 1bz;
assign  P1[4]  = gpio1_dir[4]?  gpio1_dout[4]  : 1bz;
assign  P1[3]  = gpio1_dir[3]?  gpio1_dout[3]  : 1bz;
assign  P1[2]  = gpio1_dir[2]?  gpio1_dout[2]  : 1bz;
assign  P1[1]  = gpio1_dir[1]?  gpio1_dout[1]  : 1bz;
assign  P1[0]  = gpio1_dir[0]?  gpio1_dout[0]  : 1bz;

assign  gpio1_din = P1;

endmodule
View Code

 

testbench

//----------------------------------------------------------------------------
//
// *File Name: omsp430ikmcu_tb.sv
//
// *Module Description:
//                       
//
// *Author(s):
//              - wuzhangquan,   wuzhangquan@foxmail.com
//
//--------------------------------------------------------------------------

`timescale  1ns/100ps
`include "openMSP430_defines.v"
module  omsp430ikmcu_tb;

parameter UART_BIT  = 8680;

//  DUT port Signal
reg         CLK;
reg         nRESET;
wire  [7:0] P1;
wire        txd;
reg         rxd;

//  Local variables
int         errors;
reg   [7:0] urxbuff;
event       urxflag;


//  Dut Instance
//---------------------------
omsp430ikmcu    DUT
    (
        .P1         (P1     ),
        .txd        (txd    ),
        .rxd        (rxd    ),

        .CLK        (CLK    ),
        .nRESET     (nRESET )
    );

//  Clock && Reset
//---------------------------
initial begin
    CLK =   0;
    forever #10 CLK =   ~CLK;
end

initial begin
    nRESET  <=  0;
    #100;   nRESET  <= 1;
end

//
//  include testcase file
//-------------------------------
`include    "testcase.v"

//
// Initialize ROM
//------------------------------
initial
  begin:deal_mem
  parameter MEM_TOP   = 65536;  //64K
  parameter MEM_START = MEM_TOP - (2<<(`PMEM_MSB+1));
  bit [7:0] mem [MEM_START : MEM_TOP-1];
     
      $readmemh(RCF,mem);

      $display("--------------------load pmem---------------------");
      $display("- ROM size  %0d                                 - ",MEM_TOP - MEM_START);
      $display("--------------------------------------------------");
      for(int i=MEM_START;i<MEM_TOP;i=i+2)
        begin
          DUT.u_sys.pmem_0.mem[(i-MEM_START)/2] = {mem[i+1],mem[i]};
          //$display("%h,%h",i,{mem[i+1],mem[i]});
        end
  end

//
//  Variables Initial
//----------------------------------------------------
initial begin
    $display("simulation is running...");
    $display("-----------------------------------------");
   
    //set time printf format 
    $timeformat(-6,3," us ",6);
    
    rxd = 1b1;
    

    // if timerout,finish the simulation
    #1_000_000_000;  
    $display("*E,Timer out %t",$time);
    $finish;
end

// uart task
//---------------------------------
// uart tx task
task  uart_putc(input logic [7:0] dat);
  bit [9:0] temp;
  temp  = {1b1,dat,1b0};
  for(int i=0;i<10;i++) #UART_BIT rxd = temp[i];
endtask

// uart rx
always  @(negedge txd)
  begin
    #(UART_BIT/2);
    if(txd==0)
      for(int i=0;i<8;i++)  #UART_BIT urxbuff[i] = txd;
    #UART_BIT;
    ->  urxflag;
  end

`ifdef  DUMP_VCD
initial
    begin
        $dumpfile("wave.vcd");
        $dumpvars;
    end
`endif

`ifdef  DUMP_FSDB
initial
    begin
    $fsdbDumpfile("wave.fsdb");
    $fsdbDumpvars();
    end
`endif

endmodule
`include "openMSP430_undefines.v"

 

omsp430ikmcu verilog代码