《open msp430应用笔记》中对应的verilog代码
mcu core顶层:omsp430.v
//---------------------------------------------------------------------------- // // *File Name: openMSP430.v // // *Module Description: // openMSP430 Top level file // // *Author(s): // - Olivier Girard, [email protected] // //--------------------------------------------------------------------------- // // $LastChangedBy: wuzhangquan [email protected] $ // $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 = 1‘b0; wire wdt_irq = 1‘b0; //============================================================================= // 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 = 1‘b0; 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 = 1‘b0; assign dbg_reset = 1‘b0; assign dma_dout = dbg_mem_din; endmodule // omsp430mcu `include "openMSP430_undefines.v"
sys顶层:
//---------------------------------------------------------------------------- // // *File Name: omsp430ik_sys.v // // *Module Description: // // // *Author(s): // - wuzhangquan, [email protected] // //--------------------------------------------------------------------------- `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 = 1‘b0; // 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(16‘h20)) 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(16‘h40)) 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(16‘h90)) 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 = { 1‘b0, // Vector 13 (0xFFFA) 1‘b0, // Vector 12 (0xFFF8) 1‘b0, // Vector 11 (0xFFF6) 1‘b0, // Vector 10 (0xFFF4) - Watchdog - 1‘b0, // Vector 9 (0xFFF2) - irq_ta0 - 1‘b0, // Vector 8 (0xFFF0) - irq_ta1 - 1‘b0, // Vector 7 (0xFFEE) 1‘b0, // Vector 6 (0xFFEC) 1‘b0, // Vector 5 (0xFFEA) 1‘b0, // Vector 4 (0xFFE8) irq_port2, // Vector 3 (0xFFE6) - irq_port2 - irq_port1, // Vector 2 (0xFFE4) - irq_port1 - 1‘b0, // Vector 1 (0xFFE2) 1‘b0}; // Vector 0 (0xFFE0 endmodule `include "openMSP430_undefines.v"
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] : 1‘bz; assign P1[6] = gpio1_dir[6]? gpio1_dout[6] : 1‘bz; assign P1[5] = gpio1_dir[5]? gpio1_dout[5] : 1‘bz; assign P1[4] = gpio1_dir[4]? gpio1_dout[4] : 1‘bz; assign P1[3] = gpio1_dir[3]? gpio1_dout[3] : 1‘bz; assign P1[2] = gpio1_dir[2]? gpio1_dout[2] : 1‘bz; assign P1[1] = gpio1_dir[1]? gpio1_dout[1] : 1‘bz; assign P1[0] = gpio1_dir[0]? gpio1_dout[0] : 1‘bz; assign gpio1_din = P1; endmodule
testbench
//---------------------------------------------------------------------------- // // *File Name: omsp430ikmcu_tb.sv // // *Module Description: // // // *Author(s): // - wuzhangquan, [email protected] // //-------------------------------------------------------------------------- `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 = 1‘b1; // 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 = {1‘b1,dat,1‘b0}; 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"
时间: 2024-11-06 07:32:15