Programing in scala .2nd edition

本文深入探讨Scala编程语言的关键概念,包括方法重载、赋值操作、数组操作、单例对象、类型匹配、模式匹配、协变与逆变等。解析Scala的函数特性,如闭包、偏函数、隐式转换,以及for语法糖和集合类型转换,帮助读者掌握Scala的高级编程技巧。

#基础

  1. scala 没有重载的操作

  2. '+ , - , * ,' and / can be used in method names 1 + 2 ==> Int object 1 调用了 +这个方法 参数 是 2
    (1).+(2)

  3. 赋值操作被转换成调用update方法 greetStrings(0) = "Hello" == >greetStrings.update(0, "Hello")

  4. 数组操作 - 4.1 ==> 1 :: twoThree 在list前面加元素 - :: 是right 操作 ==> twoThree.::(1)

  5. 函数写法:

    • def add(b: Byte): Unit = sum += b
    • 简写为def add(b: Byte) { sum += b },因为只有赋值操作 1
  6. Singleton objects

    • 6.1 当一个单例对象名字和类名相同时,称为类的 companion object
    • 6.2 可以相互访问私有变量
    • 6.3 singleton object 持有所有静态方法,并且是类的第一个对象, 不能接受参数
  7. 符号意义

    • 7.1 => 转换 >> var increase = (x: Int) => x + 1
    • 7.2 _ 占位符,需要填入内容 多个_的时候,顺序对应参数的位置 代表这个参数列表 someNumbers.foreach(println _)
      def sum(a: Int, b: Int, c: Int) = a + b + c ==> val a = sum _
  8. 闭包 (x: Int) => x + 1 不是

  9. scala 可以 在 子类 把父类定义的方法 变为 变量

    • Java’s four namespaces are fields, methods, types, and packages
    • Scala’s two namespaces are:
      • values (fields, methods, packages, and singleton objects)
      • types (class and trait names) 因为scala的变量和方法在一个namespace,所以无参数的方法可以被override称为val变量
  10. scala =>trait 不能定义带参数的构造函数

    • trait NoPoint(x: Int, y: Int) // Does not compile
  11. 推荐使用类型匹配 match 代替isInstanceOf 类型判断 和 asInstanceOf 类型转换

    def generalSize(x: Any) = x match {
        case s: String => s.length
        case m: Map[_, _] => m.size
        case _ => -1
    }
- sion expr has type String, say, you write:
expr.isInstanceOf[String]
To cast the same expression to type String, you use:
  expr.asInstanceOf[String]
  1. 范型匹配
    def isIntIntMap(x: Any) = x match {
           case m: Map[Int, Int] => true
           case _ => false
         }
    //====没有类型保存,所以不能匹配范型====
    isIntIntMap(Map("abc" -> "abc"))
    res20: Boolean = true
  1. 数组到范型可以,数组有特殊处理,类型随值一起保存
def isStringArray(x: Any) = x match {
                 case a: Array[String] => "yes"
                 case _ => "no"
 }

模式匹配:

selector match {
  pattern1 => <body1>
  pattern2 => <body2>
  ...
}

###pattern总结起来大约以下几类:

  • Wildcard patterns // _ 统配
  • Constant patterns // 常量
  • Variable patterns // 变量
  • Constructor patterns // 构造函数
  • Sequence patterns // 比如List(,). 如果需要匹配剩余的话使用List(0,_*)
  • Tuple patterns // (a,b,c)
  • Typed patterns // 使用类型匹配 case a:Map[,]
  • asInstanceOf[]
  • isInstanceOf[]
  • note(dirlt):这里需要注意容器类型擦除.Array例外因为这个是java内置类型

###sealed关键字

  • sealed class必须和subclass在同一个文件内。
  • 其修饰的trait,class只能在当前文件里面被继承
  • 用sealed修饰这样做的目的是告诉scala编译器在检查模式匹配的时候,让scala知道这些case的所有情况,scala就能够在编译的时候进行检查,看你写的代码是否有没有漏掉什么没case到,减少编程的错误。

##List 类型:

  • list type 是covariant.协变的,如果S是T的子类,List[S] 也是 list[T]的子类
  • empty list 是 List[Nothing]的类型,Nothing是scala继承的最底层类,
  • val xs: List[String] = List() // 空list 是任何类型的子类
  • Nil是空list
  • List("apples", "oranges", "pears") <==>"apples" :: ("oranges" :: ("pears" :: Nil))
  • :: 是一个case class x :: xs ==> ::(x,xs) ==> xs.::(x)

##Scala的成员变量

  • var hour = 12
  • get 方法 hour
  • set 方法 hour_=

class Time {
    var hour = 12
    var minute = 0
}

class Time {
    private[this] var h = 12
    private[this] var m = 0
    def hour: Int = h
    def hour_=(x: Int) { h = x }
    def minute: Int = m
    def minute_=(x: Int) { m = x }
}

##Scala函数的泛型特性——逆变与协变

trait Function1[-T, +U] {
  def apply(x: T): U
}

###“+”表示协变,而“-”表示逆变。

  • C[+T]:如果A是B的子类,那么C[A]是C[B]的子类。<==协变--作为返回值--返回该类或者子类
  • C[-T]:如果A是B的子类,那么C[B]是C[A]的子类。 <==逆变 --作为参数--输入该类或者父类
  • C[T]:无论A和B是什么关系,C[A]和C[B]没有从属关系。 Scala规定,协变类型只能作为方法的返回类型,而逆变类型只能作为方法的参数类型。

###协变

  • class A; class B; class C extends B;
  • val t2 = (p:A)=>new C //定义A=>C类型的函数
  • val t3:A=>B = t2 //可以把 A=>C类型的函数赋值给 A=>B类型的

总结: 返回子类的变化(A=>C) 可以 转换(赋值) 为 转换父类的变化(A=>B)

###逆变

  • val f1 = (x:B)=>new A //定义B=>A类型的函数
  • val f2 : C =>A = f1 //把B=>A类型的函数赋值给 C=>A 类型的

总结:输入参数父类B转换A的类型 可以 赋值 输入参数子类C转换A的类型

###类型边界

  • 上边界 T <: Animal => Animal的子类

##类型比较运算符

=:= (type equality) typeOf[List[java.lang.String]] =:= typeOf[List[Predef.String]]

##scala抽象成员

  • type
  • metohod
  • val
  • var
trait Abstract {
    type T
    def transform(x: T): T
    val initial: T
    var current: T
}

class Concrete extends Abstract {
    type T = String
    def transform(x: String) = x + x
    val initial = "hi"
    var current = initial
}

###初始化抽象vals

  • 变量赋值在传入构造器之前
  • 定义在子类的val变量,在父类初始化之后赋值

###未初始化字段出错解决

  • 预定义字段==>在父类初始化之前初始化字段
  • Pre-initialized fields in an anonymous class expression
new {
    val numerArg = 1 * x
    val denomArg = 2 * x
} with RationalTrait

Pre-initialized fields in an object definition

object twoThirds extends {
    val numerArg = 2
    val denomArg = 3
} with RationalTrait
  • Lazy vals ==>使用的时候初始化
object Demo {
lazy val x = { println("initializing x"); "done" }
}

##Traits

  • 基础代码重用单元
  • 包含方法和字段
  • 混合多个被class使用
  • 拓展简单接口为复杂接口
  • 相当于工具类
  • 用 with 连接, 可以多个

###使用抽象类还是Traits

  • 行为不会被重用,使用具体类
  • 在多个不相关的类重用,使用trait, trait类似接口可以多继承
  • 需要继承java代码,使用抽象类
  • 关注效率的,使用类,java runtimes 调用类方法比接口方法快,Traits 需要编译成 interface 额外开销

##implicits

  • 允许编译器自动选择处理类型不匹配的调用
  • 必须定义 implicits 编译器才会使用
  • variable , function, object definition
  • 需要import 指定的implicits,再import的范围有效
  • 理解为自动调用的转换方法
  • 只调用一次类型转换
  • 只有在类型不匹配的时候起作用
  • 命名的时候表示这是一个类型转换

###调用场景

  • 赋值到一个预期的类型 val i:Int = 3.5 <== implict def doubleToInt(x:double) = x.toInt
  • 接受的参数类型和方法的类型不匹配的情况
  • implicit parameters
  • 自动添加缺失的参数列表,完成调用
  • 在方法定义的参数列表的最后或者定义类的时候
  • def greet(name:String)(implicit prompt : PreferredPrompt) { prompt.XXX}
  • -Xprint:typer

##for 语法

  • for (seq ) yield expr
  • seq ==> 一组,generators,definitions,filters,分号分割
  • expr 返回 一个数组
  • for (p <- persions;n = p.name ; if(n startsWith "To")) yield
  • 所有for语句都可以转换为高级方法 map , flatMap,withFilter

##java集合类型转换

import conversions.javaConversions._

偏函数

  • Created by xifei on 16-9-7.
  • 偏函数是只对函数定义域的一个子集进行定义的函数。 scala中用scala.PartialFunction[-T, +S]类来表示
  • 函数 y = f(x) ,每个x都有对应的y值
  • 偏函数 x不一定有对应的y值
  • akka部分应用函数, 是指一个函数有N个参数, 而我们为其提供少于N个参数, 那就得到了一个部分应用函数.
<think>我们正在处理用户关于ISE编程过程中"DONE信号未变高"的问题。根据用户提供的引用内容,虽然引用是关于字符型和EOF比较的,但用户明确指出这些引用仅供参考,实际需求是解决DONE信号未变高的问题。因此,我们将忽略引用内容,专注于FPGA编程中DONE信号的问题。 在FPGA编程中,DONE信号未变高通常表示配置过程未成功完成。这可能是由多种原因引起的,包括硬件问题、配置设置问题、时序问题或电源问题等。 解决步骤: 1. 检查硬件连接: - 确认下载电缆连接正确且牢固,特别是TCK、TDI、TDO、TMS等JTAG信号线。 - 检查目标板的电源是否稳定,电压值是否在要求范围内。 - 检查FPGA的配置引脚(如PROGRAM_B、INIT_B、DONE等)的连接是否正确。 2. 检查配置模式: - 确认ISE中设置的配置模式(如JTAG、Master SPI、Slave SelectMAP等)与硬件设计一致。 - 如果是使用JTAG模式,确保链路上没有其他器件干扰,或者如果有多器件,链路的连接顺序正确。 3. 观察INIT_B信号: - INIT_B信号在配置开始时会被拉低,在清空配置内存后拉高。如果INIT_B一直为低,说明配置存储器初始化失败,可能是时钟问题或电源问题。 - 检查配置时钟(CCLK)是否正常,频率是否合适。 4. 检查设计中的时序约束和时钟: - 如果设计中的时钟或时序问题导致FPGA无法正确启动,DONE信号可能不会变高。确保设计满足时序要求,特别是与启动相关的逻辑。 5. 检查配置数据: - 确保生成的比特流文件正确,没有损坏。可以尝试重新生成比特流文件并重新下载。 6. 其他可能的原因: - 电源噪声或纹波过大,导致配置过程中出现错误。 - FPGA本身或配置存储器(如PROM)损坏。 建议的调试方法: - 使用示波器或逻辑分析仪监测配置过程中的关键信号:PROGRAM_B、INIT_B、DONE、CCLK(如果使用主模式)以及JTAG信号(TCK、TDI、TDO、TMS)。 - 观察INIT_B信号是否在复位后变高(表示初始化成功),然后观察配置数据是否通过TDI输入,最后观察DONE信号是否尝试变高(即使没有成功)。 - 如果使用JTAG模式,可以通过iMPACT的调试功能查看JTAG链的识别情况。 如果以上步骤无法解决问题,可能需要考虑更换FPGA或配置存储器,或者检查PCB设计是否存在问题。 由于用户没有提供具体的硬件环境和配置方式,以上建议为一般性解决方案。 生成相关问题: 1. 如何检查JTAG链是否正常工作? 2. FPGA配置过程中INIT_B信号一直为低是什么原因? 3. 在ISE中如何设置配置模式? 4. 如何通过示波器调试FPGA配置问题? 5. FPGA配置失败可能由哪些硬件问题引起?</think>### ISE编程中DONE信号未变高的解决方案 当ISE编程时出现"Programming terminated. DONE signal did not go high"错误,表明FPGA配置过程未成功完成。以下是系统性的解决步骤: 1. **检查硬件连接** - 确认JTAG下载线连接牢固,接口无物理损伤 - 验证目标板供电稳定(核心电压误差≤±5%),使用示波器检测电源纹波(建议<50mV) - 检查`PROG_B`、`INIT_B`、`DONE`等配置引脚的上拉电阻(典型值4.7kΩ)是否正常[^1] 2. **配置时钟验证** - 主模式:测量CCLK输出频率(默认6MHz)是否在FPGA器件支持的范围内 - 从模式:确认外部配置时钟稳定且满足时序要求 - 使用示波器捕获CCLK波形,检查是否存在振铃或过冲 3. **JTAG链诊断** ```tcl # 在iMPACT控制台执行 setCable -port auto identify -inspect ``` - 确认能识别到FPGA器件ID - 检查多器件链中所有器件均被正确枚举 4. **配置模式设置** - 在ISE工程中: ```properties Properties → Configuration Options → Configuration Rate = 6 (默认值) Config Mode = JTAG (根据硬件选择) ``` - 确保`BitGen`选项中的`DriveDone`属性设为`Yes` 5. **信号监测** 关键信号正常时序: $$T_{config} = T_{PROG\_B↓} + T_{INIT\_B↑} + T_{CFG\_DATA} + T_{DONE↑}$$ 使用逻辑分析仪捕获: - `PROG_B`脉冲宽度 > 300ns - `INIT_B`低电平时间 ≈ 5-10个CCLK周期 - `DONE`应在配置数据发送后500ms内变高 6. **固件级处理** - 添加配置监控逻辑(适用于调试): ```verilog always @(posedge done) begin if (done) $display("CONFIG SUCCESS"); else $fatal("DONE signal failure"); end ``` - 尝试使用`STARTUP_SPARTAN6`原语强制拉高DONE(仅应急方案) 7. **高级排查** - 检测PCB上`DONE`信号走线阻抗(单端50Ω) - 扫描JTAG信号完整性:上升时间应 < 0.3 * 时钟周期 - 更换配置存储芯片(如Platform Flash) **典型故障分布**: - 电源问题 35% - JTAG连接不良 25% - 配置时钟异常 20% - 比特流错误 15% - FPGA物理损坏 5%
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值